diff --git a/docs/GAMIFICATION_DESIGN.md b/docs/GAMIFICATION_DESIGN.md new file mode 100644 index 0000000..049a1c3 --- /dev/null +++ b/docs/GAMIFICATION_DESIGN.md @@ -0,0 +1,201 @@ +# Duoqi 游戏化机制设计 + +本文记录 Duoqi 第一版游戏化机制。目标是在不增加过重系统复杂度的前提下,让挑战、主题路线、排行榜、商店和个人资料形成稳定的学习循环。 + +## 设计目标 + +- 降低开始学习的心理成本:一次挑战应能在 2-4 分钟内完成。 +- 让错误有轻微成本,但不要让新用户过早被卡死。 +- 用连续学习、等级和主题路线提供长期目标。 +- 第一版加入看广告恢复,让免费用户能继续挑战,也为后续订阅权益留下清晰对比。 +- 道具先保持少量、高价值、易理解,避免背包系统过早复杂化。 + +## 核心循环 + +第一版推荐循环: + +1. 用户选择一个主题路线。 +2. 完成 1 组挑战,每组 5 题。 +3. 答题后获得即时反馈、知识卡和 XP。 +4. 挑战完成后推进主题进度、每日任务和连续学习。 +5. 资源不足时,用户可看广告恢复爱心或挑战次数。 +6. 用户通过 XP 升级、金币购买道具、参与本周排行榜。 + +原因:学习类产品需要把“我今天要做什么”压缩到一个清楚的小目标。5 题一组既有完整感,又不会让用户觉得负担重。 + +## 爱心机制 + +| 项目 | 第一版规则 | +|---|---:| +| 免费用户最大爱心 | 5 颗 | +| 答错扣除 | 每错 1 题扣 1 颗 | +| 答对 | 不扣爱心 | +| 爱心自然恢复 | 每 30 分钟恢复 1 颗 | +| 每日首次进入 | 送 1 颗,最多不超过上限 | +| 新用户保护 | 前 3 天最低保留 1 颗,不因答错完全卡死 | +| Plus 用户 | 无限爱心,或不被爱心阻断 | + +原因:5 颗爱心足以制造认真答题的感觉,但不会因为一两次错误造成强挫败。30 分钟恢复能形成自然回访点。新用户保护用于降低早期流失。 + +## 每日挑战次数 + +第一版保留每日挑战次数,但建议把它定义为“每日高奖励挑战次数”,而不是完全禁止继续学习。 + +| 项目 | 第一版规则 | +|---|---:| +| 每日高奖励挑战 | 3 组 | +| 第 4 组之后 | XP 正常,金币和宝箱概率降低 | +| 看广告恢复 | 每次恢复 1 组高奖励挑战 | +| Plus 用户 | 高奖励次数提升到 8 组或无限 | + +原因:爱心控制错误成本,每日高奖励次数控制经济系统产出。这样高手用户仍可继续学习,但不能无限刷金币和宝箱。 + +## 看广告恢复 + +看广告恢复是第一版机制,不作为后续可选项。它用于让免费用户在资源耗尽时继续挑战,同时建立 Plus 订阅的价值锚点。 + +### 可恢复资源 + +| 恢复项 | 广告完成后的效果 | 建议限制 | +|---|---|---| +| 恢复爱心 | 爱心恢复至上限 5 颗 | 每日最多 3 次 | +| 恢复高奖励挑战 | 恢复 1 组每日高奖励挑战 | 每日最多 3 次 | +| 连续学习保护 | 当天补一次连续学习保护 | 每 7 天最多 1 次广告恢复 | + +### 触发入口 + +- 首页阻断弹窗:爱心为 0 或高奖励次数为 0 时,引导去商店恢复。 +- 商店页:展示“看视频拿回冒险资源”。 +- 个人资料页:连续学习即将中断时提示保护。 + +### 奖励发放原则 + +- 必须等广告 SDK 返回完成状态后再发奖励。 +- 奖励应由服务端或 repository 的奖励服务统一结算,不由 UI 直接改进度。 +- 如果广告加载失败,应展示“稍后再试”,不能扣资源或吞掉恢复机会。 +- Plus 用户不需要看广告恢复;同入口应展示订阅权益或直接恢复。 + +原因:看广告恢复既能缓解免费用户被卡住的挫败,也能产生商业化入口。但如果不限制次数,会破坏爱心和每日次数的意义;如果失败处理不好,会让用户对系统信任下降。 + +## XP 与等级 + +第一版建议 50 个用户等级。 + +| 等级段 | 每级所需 XP | 目的 | +|---|---:|---| +| Lv.1-5 | 100, 120, 150, 180, 220 | 新手快速升级 | +| Lv.6-10 | 260, 300, 350, 400, 460 | 建立成长感 | +| Lv.11-20 | 520 起,每级 +80 | 稳定成长 | +| Lv.21-35 | 1400 起,每级 +120 | 中期目标 | +| Lv.36-50 | 3300 起,每级 +180 | 长期目标 | + +XP 奖励: + +| 行为 | XP | +|---|---:| +| 答对普通题 | 10 | +| 答对困难题 | 15 | +| 答错后看解析 | 3 | +| 完成 1 组挑战 | 20 | +| 全对完成挑战 | 额外 30 | +| 首次获得知识卡 | 15 | +| 完成每日任务 | 30-60 | +| 完成主题节点 | 80-120 | + +原因:XP 不能只奖励答对,否则弱用户会逐渐退出。少量奖励“看解析”和“完成挑战”,能把学习过程本身也变成正反馈。 + +## 连续学习与连对 + +第一版区分两个概念: + +| 概念 | 定义 | 用途 | +|---|---|---| +| 连续学习 | 每天至少完成 1 组挑战 | 长期留存 | +| 连对 | 单次挑战中连续答对题数 | 即时爽感 | + +连续学习奖励: + +| 连续天数 | 奖励 | +|---:|---| +| 3 天 | 小宝箱 | +| 7 天 | 连胜护盾 x1 | +| 14 天 | 双倍 XP 药水 x1 | +| 30 天 | 限定徽章或吉祥物装扮 | +| 100 天 | 稀有头像框或称号 | + +连对奖励: + +| 连对数 | 奖励 | +|---:|---| +| 3 连对 | +5 XP | +| 5 连对 | +10 XP,吉祥物特殊反馈 | +| 10 连对 | +25 XP,宝箱概率提升 | + +原因:连续学习负责习惯,连对负责局内情绪峰值。两者不要混在一个文案里,否则用户难以理解。 + +## 道具 + +第一版道具保持 4 个: + +| 道具 | 效果 | 获取方式 | +|---|---|---| +| 连胜护盾 | 断签时保护 1 天 | 7 日奖励、广告、商店 | +| 双倍 XP 药水 | 15 分钟内 XP x2 | 宝箱、任务、商店 | +| 爱心补给 | 恢复满爱心 | 广告、升级奖励、商店 | +| 提示羽毛 | 答题时排除 1 个错误选项 | 每日任务、金币购买 | + +原因:这些道具都直接服务学习体验。第一版不加入攻击他人、偷取资源、随机惩罚类道具,避免破坏温和公平的产品气质。 + +## 金币与商店 + +金币来源: + +| 行为 | 金币 | +|---|---:| +| 每日首组挑战 | 20 | +| 完成每日任务 | 30-80 | +| 升级 | 100 | +| 完成主题节点 | 50 | +| 宝箱 | 20-200 | + +商店价格: + +| 商品 | 价格 | +|---|---:| +| 提示羽毛 x1 | 80 | +| 爱心补给 x1 | 150 | +| 双倍 XP 药水 x1 | 250 | +| 连胜护盾 x1 | 400 | +| 吉祥物装扮 | 800-3000 | + +原因:金币要让用户 2-5 天能买到一个有价值道具。价格太低会让资源失去意义,价格太高会让商店像摆设。 + +## 排行榜 + +第一版排行榜建议使用本周 XP,不使用总 XP。 + +- 每周一刷新。 +- 按本周 XP 排名。 +- 每组 20-30 人。 +- 前 3 名获得金币、徽章碎片或头像框。 +- 第一版不做降级惩罚。 + +原因:总 XP 会让新用户永远追不上老用户。本周 XP 更公平,也更能制造周期性回流。 + +## 第一版 MVP 参数 + +```text +爱心:5 颗 +自然恢复:30 分钟 1 颗 +挑战:每组 5 题 +每日高奖励挑战:3 组 +看广告恢复爱心:每日最多 3 次,恢复满爱心 +看广告恢复高奖励挑战:每日最多 3 次,每次恢复 1 组 +看广告保护连续学习:每 7 天最多 1 次 +普通答对:10 XP +完成挑战:20 XP +全对奖励:30 XP +等级:50 级 +第一版道具:连胜护盾、双倍 XP、爱心补给、提示羽毛 +排行榜:本周 XP +``` diff --git a/docs/gamification-server-plan.md b/docs/gamification-server-plan.md new file mode 100644 index 0000000..adcd05f --- /dev/null +++ b/docs/gamification-server-plan.md @@ -0,0 +1,134 @@ +# 游戏化服务端实施计划 + +> 来源设计文档:[docs/GAMIFICATION_DESIGN.md](./GAMIFICATION_DESIGN.md) +> 创建时间:2026-05-11 +> 状态标记:`[ ]` 未开始,`[~]` 进行中,`[x]` 已完成,`[!]` 阻塞或需产品确认 + +## 目标 + +把第一版游戏化规则落到服务端可裁决、可持久化、可审计的实现中。客户端负责展示和交互,服务端负责挑战组、资源消耗、奖励结算、背包库存、周榜统计和广告恢复幂等。 + +## 当前差异 + +- 当前挑战接口以单题为单位,设计要求一组挑战 5 题。 +- 当前每日挑战次数更接近“可挑战次数”,设计要求改为“每日高奖励挑战次数”,次数耗尽后仍可继续学习。 +- 当前等级为固定 400 XP 一级,设计要求 50 级分段曲线。 +- 当前已有红心、订阅、广告恢复 session、基础 XP、连对 XP 和排行榜底座,但还缺金币、道具、背包、任务、挑战组完成奖励和本周 XP 榜。 +- 当前排行榜仍按累计 XP 排名,设计要求按本周 XP 排名,每周一刷新。 + +## 执行原则 + +- 先更新 `src/db/schema.ts`,再通过 `bun run db:generate` 生成迁移文件。 +- 服务端奖励统一通过一个奖励结算层发放,避免 UI 或单个 route 直接修改资源。 +- 所有资源变更必须有幂等边界或流水记录,尤其是广告恢复、购买、挑战完成和排行榜结算。 +- 保留现有 `/v1/rewards/ad-recovery/session` 和 `/v1/rewards/ad-recovery/complete` 作为广告恢复主入口。 +- 调整公开接口后同步更新 `docs/api-reference.md`。 +- 每完成一个阶段至少运行 `bun run typecheck`、`bun run test`;涉及 lint 规则时运行 `bun run lint`。 + +## Phase G0:规则常量与数据模型 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G0-1 | 梳理游戏化规则常量模块 | [ ] | 新增集中规则定义,覆盖红心、挑战组、XP、等级、金币、道具、广告恢复、周榜周期 | +| G0-2 | 新增挑战组数据模型 | [ ] | 支持 challenge session、session answers、组状态、正确数、完成时间、幂等提交 | +| G0-3 | 新增钱包和道具库存模型 | [ ] | 支持金币余额、道具库存、道具获得/消耗流水 | +| G0-4 | 新增奖励流水模型 | [ ] | 记录奖励来源、幂等 key、奖励快照、发放前后状态 | +| G0-5 | 新增每日任务或每日进度模型 | [ ] | 可统计每日首组挑战、每日任务完成、每日高奖励次数 | +| G0-6 | 新增周 XP 统计模型或扩展周榜快照 | [ ] | 可按自然周统计 XP,支持每周一刷新和历史快照 | +| G0-7 | 生成并提交数据库迁移 | [ ] | `db/migrations/` 包含 schema 变更,迁移文件不被 `.gitignore` 遗漏 | + +## Phase G1:挑战组与答题结算 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G1-1 | 实现创建挑战组服务 | [ ] | 一次返回 5 题,题目不泄露正确答案,绑定 track/node/chapter | +| G1-2 | 实现挑战组答题提交 | [ ] | 单题提交可幂等记录,重复提交不会重复扣资源或发奖励 | +| G1-3 | 实现挑战组完成结算 | [ ] | 组内 5 题完成后统一计算完成奖励、全对奖励、主题节点进度和每日高奖励状态 | +| G1-4 | 调整红心扣除边界 | [ ] | 答错扣 1 颗;Plus 用户不被红心阻断;新用户前 3 天最低保留 1 颗 | +| G1-5 | 调整每日高奖励挑战次数 | [ ] | 免费用户每日 3 组,Plus 8 组或按产品确认无限;次数为 0 后仍可继续学习但高价值奖励降级 | +| G1-6 | 更新挑战 API DTO | [ ] | `/challenges/next` 或新增 session API 能表达组、题、组进度、资源状态 | +| G1-7 | 添加挑战组测试 | [ ] | 覆盖创建、答对、答错、重复提交、完成结算、资源不足和 Plus 分支 | + +## Phase G2:XP、等级、连续学习和知识卡奖励 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G2-1 | 实现 50 级等级曲线 | [ ] | Lv.1-50 按设计表计算,`xpToNextLevel` 准确,超过 50 级有明确封顶或溢出策略 | +| G2-2 | 扩展 XP 奖励来源 | [ ] | 支持普通题 10、困难题 15、看解析 3、完成挑战 20、全对 30、首次知识卡 15、每日任务、主题节点奖励 | +| G2-3 | 修正连对奖励 | [ ] | 3 连对 +5,5 连对 +10,10 连对 +25,并返回客户端可展示奖励 | +| G2-4 | 将连续学习改为按挑战组完成计算 | [ ] | 每天至少完成 1 组挑战才更新 streak,不再依赖当天正确题数阈值 | +| G2-5 | 实现连续学习里程碑奖励 | [ ] | 3/7/14/30/100 天奖励可发放且不可重复领取 | +| G2-6 | 实现每日首次进入送红心 | [ ] | 每日首次 bootstrap 或专用 check-in 最多补 1 颗,不超过上限 | +| G2-7 | 添加 XP/streak 测试 | [ ] | 覆盖等级边界、首次知识卡、完成组奖励、全对奖励、看解析奖励、连续学习保护 | + +## Phase G3:金币、商店和道具 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G3-1 | 实现金币发放服务 | [ ] | 支持每日首组挑战 20、每日任务 30-80、升级 100、主题节点 50、宝箱 20-200 | +| G3-2 | 实现宝箱奖励服务 | [ ] | 支持基础概率、10 连对概率提升、高奖励次数耗尽后的概率降级 | +| G3-3 | 实现道具库存服务 | [ ] | 支持连胜护盾、双倍 XP 药水、爱心补给、提示羽毛的获得和消耗 | +| G3-4 | 实现商店商品和购买接口 | [ ] | 商品价格符合设计:提示羽毛 80、爱心补给 150、双倍 XP 250、连胜护盾 400、装扮 800-3000 | +| G3-5 | 实现道具使用接口 | [ ] | 爱心补给恢复满心,双倍 XP 药水 15 分钟生效,提示羽毛返回可排除选项,连胜护盾可保护断签 | +| G3-6 | 更新 bootstrap/shop DTO | [ ] | 客户端能拿到金币、库存、可购买商品、广告商品、订阅权益 | +| G3-7 | 添加金币/商店测试 | [ ] | 覆盖余额不足、重复购买、使用道具、药水时效、库存扣减和流水记录 | + +## Phase G4:广告恢复与订阅权益对齐 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G4-1 | 对齐广告恢复奖励到统一奖励服务 | [ ] | session complete 后通过统一奖励结算层发放,记录奖励流水 | +| G4-2 | 确认恢复爱心规则 | [ ] | 免费用户广告恢复直接恢复至 5 颗,每日最多 3 次 | +| G4-3 | 确认恢复高奖励挑战规则 | [ ] | 每次只恢复 1 组高奖励挑战,每日最多 3 次 | +| G4-4 | 确认连续学习保护规则 | [ ] | 每 7 天最多广告恢复 1 次,当天补一次保护 | +| G4-5 | 收敛旧恢复接口用途 | [ ] | 旧的直接恢复接口仅保留内部、测试或明确废弃,并在 API 文档中说明 | +| G4-6 | 明确 Plus 分支 | [ ] | Plus 用户无需看广告;同入口返回订阅权益或已订阅原因,不消耗广告次数 | +| G4-7 | 添加广告恢复回归测试 | [ ] | 覆盖 idempotency、过期、provider token 缺失、每日上限、Plus、重复 complete | + +## Phase G5:本周排行榜与周期结算 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G5-1 | 改造排行榜数据源为本周 XP | [ ] | 排行榜不再按累计 XP 排名,展示本周 XP | +| G5-2 | 实现每周一刷新逻辑 | [ ] | 自然周边界清晰,UTC/本地时区策略写入代码注释和文档 | +| G5-3 | 实现 20-30 人分组 | [ ] | 每个用户进入稳定榜组,分页和我的排名基于组内排名 | +| G5-4 | 实现前三奖励结算 | [ ] | 周结算给前 3 名发金币、徽章碎片或头像框奖励,幂等执行 | +| G5-5 | 暴露周榜元信息 | [ ] | API 返回 weekStart、weekEnd、nextRefreshAt、groupId、rank、rewardPreview | +| G5-6 | 添加排行榜测试 | [ ] | 覆盖周 XP 累加、分组、我的排名、周结算、重复结算 | + +## Phase G6:API 文档、Admin 和运维 + +| # | 任务 | 状态 | 验收标准 | +|---|------|------|----------| +| G6-1 | 更新 `docs/api-reference.md` | [ ] | 文档只保留最终客户端契约,包含挑战组、奖励、商店、背包、周榜、错误码 | +| G6-2 | 更新 `docs/implementation-plan.md` | [ ] | 将本计划作为 Phase 1d 或 Game Economy 阶段索引进去 | +| G6-3 | 增加 Admin 配置或只读查看能力 | [ ] | 管理端至少能查看用户金币、道具、奖励流水、广告恢复记录 | +| G6-4 | 增加 E2E 或集成测试 | [ ] | 覆盖游客登录、完成挑战组、广告恢复、购买道具、周榜查询 | +| G6-5 | 增加定时任务入口 | [ ] | 周榜结算和订阅/资源周期任务有可部署入口,支持手动 dry-run | +| G6-6 | 完成最终验证 | [ ] | `bun run typecheck`、`bun run test`、`bun run lint` 通过或记录明确环境阻塞 | + +## 推荐执行顺序 + +1. G0 数据模型与规则常量。 +2. G1 挑战组会话与完成结算。 +3. G2 XP、等级、连续学习规则。 +4. G3 金币、道具、商店。 +5. G4 广告恢复接入统一奖励服务。 +6. G5 本周排行榜与周期结算。 +7. G6 文档、Admin、E2E 和运维入口。 + +## 需要产品确认的决策点 + +- Plus 用户的每日高奖励挑战次数采用 8 组还是无限。 +- 等级达到 Lv.50 后是否继续累计 XP,以及 `xpToNextLevel` 如何展示。 +- 宝箱概率和高奖励次数耗尽后的降级比例。 +- 排行榜前三奖励的具体数值:金币、徽章碎片、头像框是否第一版都上线。 +- 吉祥物装扮、头像框、称号是否第一版需要完整库存模型,还是先作为奖励流水中的展示型权益。 + +## 完成定义 + +- 服务端可以独立裁决所有第一版游戏化资源和奖励。 +- 客户端不能通过直接改本地状态绕过红心、挑战次数、金币、道具和广告恢复限制。 +- 所有可重复触发的奖励都有幂等保护。 +- 所有资源变更可追踪来源和结果。 +- API 文档与真实路由、DTO、错误码保持一致。