Files
Genarrative/docs/technical/M4_RPG_RUNTIME_STORY_SPACETIMEDB_BASELINE_2026-04-21.md
kdletters f8ea3b704f
Some checks failed
CI / verify (push) Has been cancelled
清理spacetimedb绑定生成
2026-04-26 20:41:11 +08:00

8.5 KiB
Raw Permalink Blame History

M4 RPG Runtime Story SpacetimeDB 基座记录2026-04-21

更新时间:2026-04-22

0. 文档目标

本文件只记录一件事:

M4 从“只有任务清单和 crate 占位”推进到“SpacetimeDB 侧已有最小可编译 story 会话基座”的真实落地结果。

本轮只落最小骨架,不扩到完整 runtime story action 迁移,不改前端交互界面设计。


1. 本轮落地范围

本轮按 M4RPG_ENTRY_RUNTIME_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md 的交叉口径,只落实下面 6 件事:

  1. 新增 server-rs/crates/module-story/ 真实 crate而不是继续停留在 README 占位。
  2. module-story 中冻结 story_session / story_event 的首版领域类型、ID 前缀、状态枚举与字段校验 helper。
  3. server-rs/crates/spacetime-module/ 中新增 story_sessionstory_event 两张表。
  4. spacetime-module 中新增 begin_story_sessioncontinue_story 两个 reducer形成最小可编译会话主链。
  5. spacetime-module 中新增 begin_story_session_and_returncontinue_story_and_return 两个 procedure让 Axum 可同步拿到结果快照。
  6. spacetime-clientapi-server 中新增最小 story session facade打通 server-rs 侧纵向调用链。

2. 本轮新增的真实工程落点

2.1 新增 crate

  1. server-rs/crates/module-story/Cargo.toml
  2. server-rs/crates/module-story/src/lib.rs

2.2 workspace 与主工程聚合

  1. server-rs/Cargo.toml
    • 已把 crates/module-story 纳入 workspace members
  2. server-rs/crates/spacetime-module/Cargo.toml
    • 已接入 module-story 依赖
  3. server-rs/crates/spacetime-module/src/lib.rs
    • 已接入 module-story 类型
    • 已新增 story_session
    • 已新增 story_event
    • 已新增 begin_story_session
    • 已新增 continue_story
    • 已新增 begin_story_session_and_return
    • 已新增 continue_story_and_return
  4. server-rs/crates/spacetime-client/src/lib.rs
    • 已新增 begin_story_session(...)
    • 已新增 continue_story(...)
  5. server-rs/crates/api-server/src/story_sessions.rs
    • 已新增 POST /api/story/sessions
    • 已新增 POST /api/story/sessions/continue

3. 当前冻结的数据口径

3.1 story_session

当前首版字段冻结为:

  1. story_session_id
  2. runtime_session_id
  3. actor_user_id
  4. world_profile_id
  5. initial_prompt
  6. opening_summary
  7. latest_narrative_text
  8. latest_choice_function_id
  9. status
  10. version
  11. created_at
  12. updated_at

当前策略:

  1. story_session 保持 private 真相表口径。
  2. 当前只解决“故事会话存在、版本递增、最新叙事状态可追踪”。
  3. 不在本轮提前塞入 quest、combat、npc、inventory 混合字段。

3.2 story_event

当前首版字段冻结为:

  1. event_id
  2. story_session_id
  3. event_kind
  4. narrative_text
  5. choice_function_id
  6. created_at

当前策略:

  1. 事件先只承接 SessionStarted / StoryContinued 两类最小事件。
  2. 先证明事件追加模型能工作,再扩到 resolve_story_action 真实子域事件。

4. 当前 reducer 口径

4.1 begin_story_session

当前负责:

  1. 校验 StorySessionInput
  2. 拒绝重复 story_session_id
  3. 写入 story_session
  4. 追加一条 SessionStarted 事件

4.2 continue_story

当前负责:

  1. 校验 StoryContinueInput
  2. 校验目标 story_session 必须存在
  3. 以事件追加方式写入 story_event
  4. 递增 story_session.version
  5. 更新 latest_narrative_text / latest_choice_function_id / updated_at

5. 当前 procedure / facade 口径

5.1 begin_story_session_and_return

当前负责:

  1. 在单次 procedure 调用里执行 begin_story_session_tx
  2. 直接返回 storySession + storyEvent 快照
  3. spacetime-clientapi-server 直接同步消费

5.2 continue_story_and_return

当前负责:

  1. 在单次 procedure 调用里执行 continue_story_tx
  2. 直接返回推进后的 storySession + storyEvent 快照
  3. 避免 Axum 再额外读取 private table

5.3 spacetime-client story facade

当前已新增:

  1. begin_story_session(...)
  2. continue_story(...)

当前策略:

  1. spacetime-client 负责把 module-story 输入 builder 映射到 generated bindings。
  2. procedure 错误统一折叠为 SpacetimeClientError,供 Axum 映射为 400 / 502

5.4 api-server story session facade

当前已新增:

  1. POST /api/story/sessions
  2. POST /api/story/sessions/continue

当前 contract

  1. 两个接口都要求 Bearer JWT。
  2. actorUserId 由 JWT claims 提供,不允许前端透传。
  3. storySessionId / eventId 由 Rust 服务端使用 module-story 的 ID helper 生成。
  4. 两个接口当前都返回:
    • storySession
    • storyEvent

6. 当前刻意未做

本轮明确没有扩到以下范围:

  1. 还没有落 resolve_story_action
  2. 还没有落 sync_runtime_snapshot_projection
  3. 还没有接入 npc_state / quest_record / battle_state / inventory_slot
  4. 还没有兼容旧 POST /api/runtime/story/actions/resolve
  5. 还没有兼容旧 GET /api/runtime/story/state/:sessionId
  6. 还没有兼容旧 POST /api/runtime/story/state/resolve
  7. 还没有兼容旧 POST /api/runtime/story/initial
  8. 还没有兼容旧 POST /api/runtime/story/continue
  9. 还没有把 server-node 现有 rpg-runtime-story 主链切换到 server-rs
  10. 还没有改任何前端交互界面设计

也就是说,本轮只是把 M4 的 SpacetimeDB 会话基座与最小 Axum facade 立起来,不宣称已经完成 runtime story 兼容迁移。


7. 验证结果

本轮已执行:

  1. cargo check -p module-story --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml
  2. cargo check -p spacetime-module --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml
  3. cargo check -p spacetime-module --target wasm32-unknown-unknown --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml
  4. npm run spacetime:generate
  5. cargo check -p spacetime-client --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml
  6. cargo check -p api-server --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml
  7. npm run check:encoding

结果:

  1. 全部通过。

8. 下一步建议

按当前节奏,后续应继续按下面顺序推进:

  1. 先冻结 story state 查询 contract明确是新 /api/story/sessions/:storySessionId/state 还是兼容旧 /api/runtime/story/state/*
  2. 再把 story_sessionruntime_snapshot 的 projection / sync 边界补清。
  3. 再把 resolve_story_action 的输入/输出与 RuntimeStoryActionRequest 对齐成下一个 reducer / procedure 设计。
  4. 再逐步把 npc / quest / treasure / combat 子域动作接成显式事件与独立 reducer。
  5. 最后再处理旧 Node runtime story 兼容接口与前端实际切换。

9. 后续增量状态(2026-04-22

在本文件记录的首轮 story session 基座之上,当前仓库又继续补了两条与 M4 story runtime 直接相关的增量切片:

  1. 已补 GET /api/story/sessions/:storySessionId/state
    • 当前只返回 storySession + storyEvents
    • 不兼容旧 RuntimeStoryActionResponse
  2. 已补 GET /api/story/battles/:battleStateId
    • 当前只返回单个 battleState
    • 供 battle 刷新、重连和后续 story 编排复用
  3. 已补 POST /api/story/npc/battle
    • 当前只承接 npc_fight / npc_spar
    • 同步返回 npcInteraction + battleState

同时,本轮还完成了以下工程收口:

  1. 已重新执行 npm run spacetime:generate
  2. 已把 spacetime-client 中 battle query 的占位实现替换为真实 procedure 调用。
  3. 已再次执行 cargo check -p spacetime-client --manifest-path D:\\Genarrative\\server-rs\\Cargo.tomlcargo check -p api-server --manifest-path D:\\Genarrative\\server-rs\\Cargo.toml 并通过。

当前仍需继续追的验证项:

  1. story_sessions / story_battles 相关二进制测试在当前机器上编译时间较长,还没有在单次时窗内拿到最终断言结果。
  2. npm run check:encoding 已启动,但尚未在单次时窗内跑完。

因此,当前准确口径应为:

  1. M4 story session / story state / battle state / NPC 开战 的最小后端编译链已经打通。
  2. runtime story 兼容接口与旧 view model 兼容仍未完成。
  3. 长时回归测试与编码检查仍在继续推进,不应提前宣称整阶段验收完成。