# spacetime-module `lib.rs` 拆分执行方案 日期:`2026-04-23` ## 1. 背景 当前 `server-rs/crates/spacetime-module/src/lib.rs` 已经超过 `9000` 行,同时混合了承载: 1. SpacetimeDB 主工程入口 2. 跨域共享类型 3. Big Fish 4. Asset Metadata 5. Runtime 6. Gameplay 7. Custom World 8. AI 9. Puzzle 10. 测试 这会直接导致: 1. 任意一个领域改动都要在同一个超大文件里定位 2. 不同玩法与领域的 reducer / procedure / helper 互相缠绕 3. 结构上已经与 `M7` 冻结的“按业务与 SpacetimeDB 聚合层次拆分目录”目标不一致 ## 2. 本轮约束 本轮拆分严格遵守以下规则: 1. 只做物理结构收口,不改 table 名、reducer 名、procedure 名。 2. 不改现有 schema 字段名、字段顺序语义与已有对外 contract。 3. 不把外部副作用搬进 SpacetimeDB reducer / procedure。 4. 允许在过渡期继续保留少量跨域 helper 在 `lib.rs`,但新增内容禁止继续直接堆回 `lib.rs`。 ## 3. 模块地图 ### 3.1 根入口 `server-rs/crates/spacetime-module/src/lib.rs` 后续只允许保留: 1. `use` 聚合 2. `mod` 声明 3. 少量跨域共享 helper 4. 迁移过渡期测试 禁止继续新增某个具体业务域的 table / reducer / procedure / tx helper。 导入导出风格同步冻结为: 1. `src/lib.rs` 对外统一优先使用 `pub use xxx::*;` 重新导出主工程模块与外部模块 crate 内容。 2. 已拆出的业务模块内部统一优先使用 `use crate::*;`,避免每个文件重复维护大段显式 `use` 列表。 3. 子模块只有遇到命名冲突、宏限制或无法从 crate 根重导出的外部符号时,才允许补局部显式 `use`。 4. 后续拆分时不再因为导入列表变长而把业务实现留在 `lib.rs`。 ### 3.2 已冻结的一级模块 1. `src/entry.rs` - 模块初始化入口 - `#[spacetimedb::reducer(init)]` 2. `src/domain_types.rs` - 跨域共享的 SpacetimeDB 类型 - 目前主要承载 NPC 开战桥接输入输出 3. `src/asset_metadata/mod.rs` - `asset_object` - `asset_entity_binding` - 资产确认与绑定 reducer / procedure 4. `src/big_fish/mod.rs` - Big Fish session / message / asset slot / runtime run - Big Fish procedure 与 tx helper 5. `src/runtime/mod.rs` - Runtime settings / snapshots / browse history / dashboard / wallet / save archive 6. `src/gameplay/mod.rs` - `story / combat / inventory / npc / quest / runtime_item / progression` 7. `src/custom_world/mod.rs` - profile / session / agent / publish / gallery / works 8. `src/ai/mod.rs` - ai task / stage / chunk / reference 9. `src/puzzle.rs` - 拼图玩法当前仍为单文件域模块,后续再决定是否继续拆目录 ### 3.3 本轮先创建的二级落位点 #### `asset_metadata/` 1. `objects.rs` 2. `bindings.rs` #### `big_fish/` 1. `tables.rs` 2. `session.rs` 3. `assets.rs` 4. `runtime.rs` #### `runtime/` 1. `settings.rs` 2. `snapshots.rs` 3. `browse_history.rs` 4. `profile.rs` #### `gameplay/` 1. `combat.rs` 2. `inventory.rs` 3. `npc.rs` 4. `progression.rs` 5. `quest.rs` 6. `runtime_item.rs` 7. `story.rs` #### `custom_world/` 1. `profile.rs` 2. `session.rs` 3. `agent.rs` 4. `publishing.rs` 5. `gallery.rs` 6. `works.rs` #### `ai/` 1. `tasks.rs` 2. `stages.rs` 3. `snapshots.rs` ## 4. 迁移顺序 为了降低脏工作区下的冲突风险,本轮按下面顺序推进: 1. 先冻结文档与 README 路由规则。 2. 先创建二级空模块文件,作为后续内容落位点。 3. 第一批先迁: - `entry.rs` - `domain_types.rs` - `asset_metadata/mod.rs` - `big_fish/mod.rs` 4. 第二批再迁: - `runtime/mod.rs` - `gameplay/mod.rs` 5. 第三批再迁: - `custom_world/mod.rs` - `ai/mod.rs` 6. `puzzle.rs` 暂时保持单文件,不在本轮强拆。 ## 5. 本轮完成标准 1. `README.md` 明确声明后续新增逻辑的落位规则。 2. 一级模块与二级空模块文件创建完成。 3. `lib.rs` 不再承载 `init`、共享 domain types、asset metadata、big fish 的实现细节。 4. `cargo check -p spacetime-module --lib` 继续通过。 5. 中文文档与 Rust 文件经过编码检查,没有写坏。 ## 6. `runtime` 域实拆记录 `2026-04-23` 追加执行 `runtime` 域真实内容拆分,目标是把根入口中的 runtime 表、procedure 与同域 tx helper 收口到 `src/runtime/`,同时保持对外 API 名称不变。 ### 6.1 已落位文件 1. `server-rs/crates/spacetime-module/src/runtime/mod.rs` - 仅保留二级模块声明与 `pub use xxx::*;` 聚合导出。 2. `server-rs/crates/spacetime-module/src/runtime/settings.rs` - 承载 `RuntimeSetting` - 承载 runtime setting 的读取、upsert procedure 与快照构建 helper。 3. `server-rs/crates/spacetime-module/src/runtime/snapshots.rs` - 承载 `RuntimeSnapshotRow` - 承载 runtime snapshot 的读取、upsert、delete 与 JSON 解析 helper。 4. `server-rs/crates/spacetime-module/src/runtime/browse_history.rs` - 承载 `UserBrowseHistory` - 承载平台浏览历史 list、upsert、clear procedure 与行转换 helper。 5. `server-rs/crates/spacetime-module/src/runtime/profile.rs` - 承载 `ProfileDashboardState` - 承载 `ProfileWalletLedger` - 承载 `ProfilePlayedWorld` - 承载 `ProfileSaveArchive` - 承载 profile dashboard、wallet ledger、play stats、save archive 投影与 snapshot 同步 helper。 ### 6.2 根入口调整 `server-rs/crates/spacetime-module/src/lib.rs` 当前只通过下面方式接入 runtime 域: 1. `mod runtime;` 2. `pub use runtime::*;` 原先留在 `lib.rs` 的 runtime setting、snapshot、profile、browse history 旧 helper 已删除,避免同名实现重复存在,也避免后续继续在根入口堆叠 runtime 业务逻辑。 ### 6.3 后续维护规则 1. 对外导出继续通过 `pub use runtime::*;` 以及 `src/runtime/mod.rs` 中的 `pub use xxx::*;` 透出。 2. `runtime` 子文件内部优先使用 `use crate::*;`,只有 SpacetimeDB table accessor trait、命名冲突或宏限制需要时才补最小显式导入。 3. 新增 runtime 相关表、procedure、reducer 或 tx helper 时,必须先按 `settings / snapshots / browse_history / profile` 判断二级落位点;不匹配时先更新本文件与 README,再新增二级模块。 4. `lib.rs` 只保留跨域共享 helper 和尚未迁出的过渡代码,不再接收 runtime 域新增实现。 ## 7. `ai` 域实拆记录 `2026-04-23` 追加执行 `ai` 域真实内容拆分,目标是把根入口中的 AI 表、procedure 与同域 tx helper 收口到 `src/ai/`,同时保持 `module-ai` 对外输入输出 contract 与 SpacetimeDB reducer / procedure 名称不变。 ### 7.1 已落位文件 1. `server-rs/crates/spacetime-module/src/ai/mod.rs` - 仅保留二级模块声明与聚合导出。 - public API 通过 `pub use stages::*;` 和 `pub use tasks::*;` 透出。 - 内部转换 helper 通过 `pub(crate) use snapshots::*;` 供 AI 子模块共享。 2. `server-rs/crates/spacetime-module/src/ai/tasks.rs` - 承载 `AiTask` - 承载 `create_ai_task` - 承载 `create_ai_task_and_return` - 承载 `start_ai_task` - 承载 `complete_ai_task_and_return` - 承载 `fail_ai_task_and_return` - 承载 `cancel_ai_task_and_return` - 承载 task 状态迁移、读取与持久化 helper。 3. `server-rs/crates/spacetime-module/src/ai/stages.rs` - 承载 `AiTaskStage` - 承载 `AiTextChunk` - 承载 `AiResultReference` - 承载 `start_ai_task_stage` - 承载 `append_ai_text_chunk_and_return` - 承载 `complete_ai_stage_and_return` - 承载 `attach_ai_result_reference_and_return` - 承载阶段流式文本聚合、阶段替换与 result reference 写入 helper。 4. `server-rs/crates/spacetime-module/src/ai/snapshots.rs` - 承载 `AiTask / AiTaskStage / AiTextChunk / AiResultReference` 的 row 与 snapshot 转换 helper。 ### 7.2 根入口调整 `server-rs/crates/spacetime-module/src/lib.rs` 当前只通过下面方式接入 AI 域: 1. `mod ai;` 2. `pub use ai::*;` 原先留在 `lib.rs` 的 AI 表、procedure 与 helper 已删除,避免根入口继续堆叠 AI 业务实现。 ### 7.3 后续维护规则 1. 对外导出继续通过 `pub use ai::*;` 以及 `src/ai/mod.rs` 中的 `pub use xxx::*;` 透出。 2. `ai` 子文件内部优先使用 `use crate::*;`,只有 `module_ai` 中的归一化函数、校验函数、ID 前缀常量等需要避免 glob 歧义的符号才补最小显式导入。 3. 新增 AI 相关表、procedure、reducer 或 tx helper 时,必须先按 `tasks / stages / snapshots` 判断二级落位点;不匹配时先更新本文件与 README,再新增二级模块。 4. `lib.rs` 不再接收 AI 域新增实现。