# M4 Module Progression SpacetimeDB 基座记录(2026-04-21) 更新时间:`2026-04-21` ## 0. 文档目标 本文件只记录一件事: **把 `module-progression` 从“只有 README 占位”推进到“SpacetimeDB 侧已有最小可编译成长真相基座”的真实落地结果。** 本轮先落等级/经验/章节计划与记账的最小领域骨架,并补上任务交付与战斗胜利的自动联动;不扩到完整 `custom-world` 章节蓝图编译或 Axum facade 全链迁移。 --- ## 1. 本轮落地范围 本轮按 `LEVEL_PROGRESS_AND_CHAPTER_NPC_AUTO_SCALING_DESIGN_2026-04-20.md` 与 `SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md` 的交叉口径,只落实下面 6 件事: 1. 新增 `server-rs/crates/module-progression/` 真实 crate,而不是继续停留在 README 占位。 2. 在 `module-progression` 中冻结 `LevelBenchmark`、`PlayerProgressionSnapshot`、`ChapterProgressionSnapshot`、`RuntimeEntityLevelProfile` 的首版领域类型。 3. 在 `module-progression` 中落地与当前 Node 版一致的等级经验曲线、参考强度曲线、章节 pseudo level 曲线与敌对战斗 fallback 规则。 4. 在 `server-rs/crates/spacetime-module/` 中新增 `player_progression`、`chapter_progression` 两张表。 5. 在 `spacetime-module` 中新增 `get_player_progression_or_default`、`grant_player_progression_experience`、`upsert_chapter_progression`、`apply_chapter_progression_ledger_entry` 及对应 procedure。 6. 用 `module-story / module-quest` 同口径方式,把成长状态固定成“单用户成长表 + 单章节计划/记账表”的最小可编译基座。 --- ## 2. 本轮新增的真实工程落点 ### 2.1 新增 crate 1. `server-rs/crates/module-progression/Cargo.toml` 2. `server-rs/crates/module-progression/src/lib.rs` ### 2.2 workspace 与主工程聚合 1. `server-rs/Cargo.toml` - 已把 `crates/module-progression` 纳入 workspace members 2. `server-rs/crates/spacetime-module/Cargo.toml` - 已接入 `module-progression` 依赖 3. `server-rs/crates/spacetime-module/src/lib.rs` - 已接入 `module-progression` 类型 - 已新增 `player_progression` - 已新增 `chapter_progression` - 已新增成长相关 reducer / procedure --- ## 3. 当前冻结的数据口径 ### 3.1 `player_progression` 当前首版字段冻结为: 1. `user_id` 2. `level` 3. `current_level_xp` 4. `total_xp` 5. `xp_to_next_level` 6. `pending_level_ups` 7. `last_granted_source` 8. `created_at` 9. `updated_at` 当前策略: 1. `player_progression` 保持 private 真相表口径。 2. 当前统一按 `user_id` 单行持久化,不在本轮拆历史 grant 日志表。 3. 若记录不存在,`procedure` 返回 `Lv.1 / 0 XP` 默认快照,但不额外写库。 ### 3.2 `chapter_progression` 当前首版字段冻结为: 1. `chapter_progression_id` 2. `user_id` 3. `chapter_id` 4. `chapter_index` 5. `total_chapters` 6. `entry_pseudo_level_millis` 7. `exit_pseudo_level_millis` 8. `entry_level` 9. `exit_level` 10. `planned_total_xp` 11. `planned_quest_xp` 12. `planned_hostile_xp` 13. `actual_quest_xp` 14. `actual_hostile_xp` 15. `expected_hostile_defeat_count` 16. `actual_hostile_defeat_count` 17. `level_at_entry` 18. `level_at_exit` 19. `pace_band` 20. `created_at` 21. `updated_at` 当前策略: 1. `chapter_progression` 先用一张表同时承接 `ChapterProgressionPlan` 与 `ChapterExperienceLedger`。 2. 当前不再额外拆计划表和记账表,避免首轮 schema 还没稳定就二次改表。 3. 主键固定为 `user_id + chapter_id` 组合衍生 ID,保证同一玩家每章只有一条真相记录。 --- ## 4. 当前 reducer / procedure 口径 ### 4.1 `get_player_progression_or_default` 当前负责: 1. 按 `user_id` 读取 `player_progression` 2. 若不存在则返回默认 `Lv.1 / 0 XP` 3. 不产生额外写入 ### 4.2 `grant_player_progression_experience` 当前负责: 1. 读取当前 `player_progression`,不存在则按默认成长态开始 2. 根据 `PlayerProgressionGrantInput` 发放经验 3. 统一更新 `level / current_level_xp / total_xp / xp_to_next_level / pending_level_ups` 4. 固定 `last_granted_source` ### 4.3 `upsert_chapter_progression` 当前负责: 1. 写入或覆盖某玩家某章节的计划快照 2. 固定章节预算、目标等级带与预期击杀数 3. 把实际记账字段初始化为 `0` ### 4.4 `apply_chapter_progression_ledger_entry` 当前负责: 1. 在已存在的章节计划上累计 `actual_quest_xp` 2. 累计 `actual_hostile_xp` 3. 累计 `actual_hostile_defeat_count` 4. 可选更新 `level_at_exit` --- ## 5. 当前刻意未做 本轮明确没有扩到以下范围: 1. 还没有把 `sceneChapterBlueprints` 的完整编译逻辑迁到 Rust。 2. 还没有落 `repeatPenalty`、超预算衰减与章节偏差评级输出。 3. 还没有把完整章节蓝图、掉落和全量 quest signal 都自动串进 `player_progression / chapter_progression`。 4. 还没有新增 Axum 的 progression facade。 5. 还没有把前端 `Lv.` 展示、任务奖励经验提示或敌对等级徽标切到 Rust 后端真相源。 也就是说,本轮只是把 `module-progression` 的 SpacetimeDB 成长基座立起来,不宣称已经完成成长系统迁移。 --- ## 6. 验证要求 本轮工程变更完成后,至少执行下面两类验证: 1. `npm run check:encoding` 2. `cargo test -p module-progression` 3. `cargo check -p spacetime-module` --- ## 7. 下一步建议 按当前节奏,后续应继续按下面顺序推进: 1. 先把章节预算编译从 Node `chapterProgressionPlanner` 平移到 Rust 领域层。 2. 再把 `npc` / `combat` 入口改为消费 `RuntimeEntityLevelProfile` 和 `chapter_progression`。 3. 再把掉落、任务物品、好感奖励并入统一奖励结算。 4. 最后再接 Axum facade、兼容 DTO 与前端成长主链。