6.4 KiB
6.4 KiB
M4 RPG Runtime Quest SpacetimeDB 基座记录(2026-04-21)
更新时间:2026-04-21
0. 文档目标
本文件只记录一件事:
把 module-quest 从“只有 README 占位”推进到“SpacetimeDB 侧已有最小可编译任务运行时基座”的真实落地结果。
本轮只落任务主状态、任务日志与最小 reducer,并补上任务交付到成长表、背包表的最小联动;不扩到完整奖励结算、Axum facade、前端任务面板或 story action 全量迁移。
1. 本轮落地范围
本轮按 AI_NATIVE_QUEST_SYSTEM_PRD_2026-04-02.md、AI_NATIVE_TASK_DRIVEN_GOAL_EXPERIENCE_PRD_2026-04-07.md 与 SPACETIMEDB_AXUM_OSS_BACKEND_REWRITE_DESIGN_2026-04-20.md 的交叉口径,只落实下面 5 件事:
- 新增
server-rs/crates/module-quest/真实 crate,而不是继续停留在 README 占位。 - 在
module-quest中冻结QuestRecord、QuestStep、QuestReward、QuestProgressSignal的首版 Rust 领域类型与校验/归一化 helper。 - 在
server-rs/crates/spacetime-module/中新增quest_record、quest_log两张表。 - 在
spacetime-module中新增accept_quest、apply_quest_signal、acknowledge_quest_completion、turn_in_quest四个 reducer。 - 用
module-story同口径方式,把任务推进固定成“主记录 + 日志追加”的最小可编译基座。 - 把
turn_in_quest.reward.items显式映射为InventoryMutation::GrantItem,在任务交付时同步写入inventory_slot。
2. 本轮新增的真实工程落点
2.1 新增 crate
server-rs/crates/module-quest/Cargo.tomlserver-rs/crates/module-quest/src/lib.rs
2.2 workspace 与主工程聚合
server-rs/Cargo.toml- 已把
crates/module-quest纳入 workspace members
- 已把
server-rs/crates/spacetime-module/Cargo.toml- 已接入
module-quest依赖
- 已接入
server-rs/crates/spacetime-module/src/lib.rs- 已接入
module-quest类型 - 已新增
quest_record - 已新增
quest_log - 已新增
accept_quest - 已新增
apply_quest_signal - 已新增
acknowledge_quest_completion - 已新增
turn_in_quest
- 已接入
3. 当前冻结的数据口径
3.1 quest_record
当前首版字段冻结为:
quest_idruntime_session_idstory_session_idactor_user_idissuer_npc_idissuer_npc_namescene_idchapter_idact_idthread_idcontract_idtitledescriptionsummaryobjectiveprogressstatuscompletion_notifiedrewardreward_textnarrative_bindingstepsactive_step_idvisible_stagehidden_flagsdiscovered_fact_idsrelated_carrier_idsconsequence_idscreated_atupdated_atcompleted_atturned_in_at
当前策略:
quest_record保持 private 真相表口径。- 当前仍沿用“一个任务一条主记录”的最小可编译策略,不在本轮拆
quest_step独立表。 objective / progress / active_step_id / status统一由steps归一化导出,避免旧接口和新真相源在同一条记录里出现漂移。
3.2 quest_log
当前首版字段冻结为:
log_idquest_idruntime_session_idactor_user_idevent_kindstatus_aftersignal_kindsignalstep_idstep_progresscreated_at
当前策略:
quest_log先作为 private 结构化日志表,不提前做 public event table。- 当前只承接
Accepted / Progressed / Completed / CompletionAcknowledged / TurnedIn五类事件。 - 后续若要接前端实时提示,再决定是否补 event table 或投影表,而不是现在先塞 UI 专用字段。
4. 当前 reducer 口径
4.1 accept_quest
当前负责:
- 校验
QuestRecordInput - 拒绝重复
quest_id - 写入
quest_record - 追加一条
Accepted日志
4.2 apply_quest_signal
当前负责:
- 校验
QuestSignalApplyInput - 校验目标
quest_record必须存在 - 只对当前 active step 应用任务信号
- 在命中信号时推进 step progress、刷新
objective / active_step_id / progress / status - 命中且未完成时追加
Progressed - 最后一条 step 完成时追加
Completed
补充约束:
- 已经
Completed / ReadyToTurnIn / TurnedIn / Failed / Expired的任务不会被重复推进。 - 信号未命中当前 active step 时,本轮 reducer 允许静默 no-op,保持幂等。
4.3 acknowledge_quest_completion
当前负责:
- 把
completion_notified标为true - 追加一条
CompletionAcknowledged日志
4.4 turn_in_quest
当前负责:
- 校验任务已处于
Completed / ReadyToTurnIn - 固定所有 step progress 为完成态
- 把任务状态切到
TurnedIn - 补齐
turned_in_at - 追加一条
TurnedIn日志 - 若存在
reward.items,同步发放到inventory_slot - 若存在
reward.items,同步发放到inventory_slot - 若
reward.experience > 0,同步发放player_progression经验 - 若存在已初始化的
chapter_progression,同步累计章节任务经验账本
5. 当前刻意未做
本轮明确没有扩到以下范围:
- 还没有落任务奖励的货币、好感、情报统一发放 reducer
- 还没有接
runtime_snapshotprojection / sync - 还没有接
story_session、npc_state的更多跨域联动 - 还没有新增 Axum 的 runtime quest facade
- 还没有把
server-node现有 quest API 切到server-rs - 还没有把 Goal Director、章节目标 handoff、前端任务 UI 切到 SpacetimeDB 真相源
也就是说,本轮只是把 module-quest 的 SpacetimeDB 任务基座立起来,不宣称已经完成任务系统迁移。
6. 验证要求
本轮工程变更完成后,至少执行下面两类验证:
npm run check:encodingcargo test -p module-questcargo check -p spacetime-module
7. 下一步建议
按当前节奏,后续应继续按下面顺序推进:
- 先把
quest_record与runtime_snapshot的投影边界补清。 - 再把
resolve_story_action内的 quest signal 分发迁到apply_quest_signal。 - 再把
turn_in_quest与npc affinity / currency / intel projection的奖励结算接成显式 reducer。 - 再把 quest reward item 的映射 helper 上提到独立领域 crate,减少
spacetime-module聚合层重复转换。 - 最后再接 Axum facade、兼容 DTO 与前端任务主链。