Prune stale docs and update .hermes content
Delete a large set of outdated documentation (many files under docs/ and .hermes/plans/, including audits, design, prd, technical, planning, assets, and todos). Update and consolidate .hermes content: refresh shared-memory pages (decision-log, development-workflow, document-map, pitfalls, project-overview, team-conventions) and several skills/references under .hermes/skills. Also modify AGENTS.md, README.md, UI_CODING_STANDARD.md, docs/README.md and .encoding-check-ignore. Purpose: clean up stale planning/audit material and keep current hermes documentation and related top-level docs in sync.
This commit is contained in:
@@ -1,273 +0,0 @@
|
||||
# M4 module-npc SpacetimeDB 基座记录(2026-04-21)
|
||||
|
||||
更新时间:`2026-04-21`
|
||||
|
||||
## 0. 文档目标
|
||||
|
||||
本文件只记录一件事:
|
||||
|
||||
**把 `module-npc` 从“只有占位 README”推进到“已有可编译 Rust 领域 contract,并接入 `SpacetimeDB` 最小 `npc_state` 真相表与社交动作 reducer/procedure”的真实落地结果。**
|
||||
|
||||
本轮只做最小基座,不扩到完整 `npc_trade / npc_gift / npc_recruit` 的全链结算迁移,也不改前端 UI。
|
||||
|
||||
---
|
||||
|
||||
## 1. 本轮落地范围
|
||||
|
||||
本轮只落实下面 6 件事:
|
||||
|
||||
1. 新增 `server-rs/crates/module-npc/` 真实 crate,而不是继续停留在目录占位。
|
||||
2. 在 `module-npc` 中冻结 `relation_state / stance_profile / npc_state` 的首版领域类型与校验 helper。
|
||||
3. 在 `module-npc` 中补齐 `build_initial_stance_profile`、`normalize_npc_state_snapshot`、`apply_npc_social_action` 等最小规则原语。
|
||||
4. 在 `server-rs/crates/spacetime-module/` 中新增 `npc_state` 表。
|
||||
5. 在 `spacetime-module` 中新增 `upsert_npc_state`、`resolve_npc_social_action` 及对应 procedure,形成最小可编译写入口。
|
||||
6. 在 `module-npc` 中新增 `resolve_npc_interaction` 的首版领域 contract,并在 `spacetime-module` 中补对应 reducer / procedure。
|
||||
|
||||
---
|
||||
|
||||
## 2. 本轮新增的真实工程落点
|
||||
|
||||
### 2.1 新增 crate
|
||||
|
||||
1. `server-rs/crates/module-npc/Cargo.toml`
|
||||
2. `server-rs/crates/module-npc/src/lib.rs`
|
||||
|
||||
### 2.2 workspace 与主工程聚合
|
||||
|
||||
1. `server-rs/Cargo.toml`
|
||||
- 已把 `crates/module-npc` 纳入 workspace members
|
||||
2. `server-rs/crates/spacetime-module/Cargo.toml`
|
||||
- 已接入 `module-npc` 依赖
|
||||
3. `server-rs/crates/spacetime-module/src/lib.rs`
|
||||
- 已接入 `module-npc` 类型
|
||||
- 已新增 `npc_state`
|
||||
- 已新增 `upsert_npc_state`
|
||||
- 已新增 `upsert_npc_state_and_return`
|
||||
- 已新增 `resolve_npc_social_action`
|
||||
- 已新增 `resolve_npc_social_action_and_return`
|
||||
- 已新增 `resolve_npc_interaction`
|
||||
- 已新增 `resolve_npc_interaction_and_return`
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前冻结的数据口径
|
||||
|
||||
### 3.1 `relation_state`
|
||||
|
||||
当前首版冻结为:
|
||||
|
||||
1. `affinity`
|
||||
2. `stance`
|
||||
|
||||
`stance` 当前只冻结 5 档:
|
||||
|
||||
1. `Hostile`
|
||||
2. `Guarded`
|
||||
3. `Neutral`
|
||||
4. `Cooperative`
|
||||
5. `Bonded`
|
||||
|
||||
当前阈值直接对齐现有前端 / Node 原语:
|
||||
|
||||
1. `< 0` -> `Hostile`
|
||||
2. `< 15` -> `Guarded`
|
||||
3. `< 30` -> `Neutral`
|
||||
4. `< 60` -> `Cooperative`
|
||||
5. `>= 60` -> `Bonded`
|
||||
|
||||
### 3.2 `stance_profile`
|
||||
|
||||
当前首版冻结为:
|
||||
|
||||
1. `trust`
|
||||
2. `warmth`
|
||||
3. `ideological_fit`
|
||||
4. `fear_or_guard`
|
||||
5. `loyalty`
|
||||
6. `current_conflict_tag`
|
||||
7. `recent_approvals`
|
||||
8. `recent_disapprovals`
|
||||
|
||||
字段策略:
|
||||
|
||||
1. 数值统一收敛到 `0 ~ 100`。
|
||||
2. 最近好评 / 反感文本统一只保留最近 `3` 条。
|
||||
3. `current_conflict_tag` 仍允许为空,不在本轮强绑世界线程 ID。
|
||||
|
||||
### 3.3 `npc_state`
|
||||
|
||||
当前首版字段冻结为:
|
||||
|
||||
1. `npc_state_id`
|
||||
2. `runtime_session_id`
|
||||
3. `npc_id`
|
||||
4. `npc_name`
|
||||
5. `affinity`
|
||||
6. `relation_state`
|
||||
7. `help_used`
|
||||
8. `chatted_count`
|
||||
9. `gifts_given`
|
||||
10. `recruited`
|
||||
11. `trade_stock_signature`
|
||||
12. `revealed_facts`
|
||||
13. `known_attribute_rumors`
|
||||
14. `first_meaningful_contact_resolved`
|
||||
15. `seen_backstory_chapter_ids`
|
||||
16. `stance_profile`
|
||||
17. `created_at`
|
||||
18. `updated_at`
|
||||
|
||||
当前策略:
|
||||
|
||||
1. `npc_state` 保持 private 真相表口径。
|
||||
2. `npc_state_id` 允许由 `runtime_session_id + npc_id` 自动派生,避免外部每次重复拼接。
|
||||
3. `relation_state` 作为显式冗余字段落表,避免每次读取都重复派生。
|
||||
4. `npc_name` 当前保留为调试与兼容聚合字段,不承担唯一键职责。
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前 reducer / procedure 口径
|
||||
|
||||
### 4.1 `upsert_npc_state`
|
||||
|
||||
当前负责:
|
||||
|
||||
1. 校验 `runtime_session_id / npc_id / npc_name`
|
||||
2. 归一化 `stance_profile`
|
||||
3. 归一化 `relation_state`
|
||||
4. 以 `npc_state_id` 为主键执行幂等写入
|
||||
|
||||
### 4.2 `resolve_npc_social_action`
|
||||
|
||||
当前只承接 **纯 NPC 关系状态** 的最小变更,不负责背包、任务、队伍、战斗副作用。
|
||||
|
||||
当前动作冻结为:
|
||||
|
||||
1. `Chat`
|
||||
2. `Help`
|
||||
3. `Gift`
|
||||
4. `Recruit`
|
||||
5. `QuestAccept`
|
||||
|
||||
当前规则:
|
||||
|
||||
1. `Chat`
|
||||
- 默认按 `max(2, 6 - chatted_count)` 推进好感
|
||||
- 递增 `chatted_count`
|
||||
- 强制标记 `first_meaningful_contact_resolved = true`
|
||||
2. `Help`
|
||||
- 若已使用过援手则拒绝
|
||||
- 默认推进 `4` 点好感
|
||||
- 写入 `help_used = true`
|
||||
3. `Gift`
|
||||
- 递增 `gifts_given`
|
||||
- 默认按 `4` 点好感推进,允许外部显式传入覆盖值
|
||||
4. `Recruit`
|
||||
- 若当前好感 `< 60` 则拒绝
|
||||
- 写入 `recruited = true`
|
||||
- 同时标记首遇已完成
|
||||
5. `QuestAccept`
|
||||
- 默认推进 `3` 点好感
|
||||
- 只改 NPC 关系侧立场数据,不直接落 quest 真相
|
||||
|
||||
当前 procedure 仅返回最新 `NpcStateSnapshot`,不在本轮提前扩出 story patch / UI 文案 contract。
|
||||
|
||||
### 4.3 `resolve_npc_interaction`
|
||||
|
||||
当前首版 `resolve_npc_interaction` 不直接承担所有跨子域副作用,而是先固定 **NPC 单次正式交互** 的最小统一结果口径。
|
||||
|
||||
当前输入冻结为:
|
||||
|
||||
1. `runtime_session_id`
|
||||
2. `npc_id`
|
||||
3. `npc_name`
|
||||
4. `interaction_function_id`
|
||||
5. `updated_at_micros`
|
||||
6. `release_npc_id`(仅为后续招募换队预留,当前不在 Rust 侧正式消费)
|
||||
|
||||
当前支持的 function 只冻结为:
|
||||
|
||||
1. `npc_preview_talk`
|
||||
2. `npc_chat`
|
||||
3. `npc_help`
|
||||
4. `npc_recruit`
|
||||
5. `npc_fight`
|
||||
6. `npc_spar`
|
||||
7. `npc_leave`
|
||||
|
||||
当前输出冻结为:
|
||||
|
||||
1. `npc_state`
|
||||
2. `interaction_status`
|
||||
3. `action_text`
|
||||
4. `result_text`
|
||||
5. `story_text`
|
||||
6. `battle_mode`
|
||||
7. `encounter_closed`
|
||||
8. `affinity_changed`
|
||||
9. `previous_affinity`
|
||||
10. `next_affinity`
|
||||
|
||||
当前规则:
|
||||
|
||||
1. `npc_preview_talk`
|
||||
- 只把交互状态切到 `Previewed`
|
||||
- 不改好感
|
||||
2. `npc_chat`
|
||||
- 复用 `resolve_npc_social_action(Chat)` 的关系推进
|
||||
- 返回 `interaction_status = Dialogue`
|
||||
3. `npc_help`
|
||||
- 复用 `resolve_npc_social_action(Help)`
|
||||
- 返回 `interaction_status = Resolved`
|
||||
4. `npc_recruit`
|
||||
- 当前只负责把 `npc_state.recruited = true`
|
||||
- 不在本轮承担 companion / roster 真相写入
|
||||
- 返回 `interaction_status = Recruited`
|
||||
5. `npc_fight`
|
||||
- 不改 `npc_state.affinity`
|
||||
- 返回 `interaction_status = BattlePending`
|
||||
- `battle_mode = Fight`
|
||||
6. `npc_spar`
|
||||
- 不改 `npc_state.affinity`
|
||||
- 返回 `interaction_status = BattlePending`
|
||||
- `battle_mode = Spar`
|
||||
7. `npc_leave`
|
||||
- 不改关系真相
|
||||
- 返回 `interaction_status = Left`
|
||||
- `encounter_closed = true`
|
||||
|
||||
当前刻意不做:
|
||||
|
||||
1. 不直接生成 `RuntimeStoryPatch`
|
||||
2. 不直接写 `companions / roster / inventory_slot`
|
||||
3. 不直接把玩家 HP / MP、切磋战斗目标、战斗奖励塞进这个 reducer
|
||||
|
||||
也就是说,这一层当前只负责把 **Node 侧 `resolveNpcInteraction` 的统一入口语义** 先冻结为可编译 contract,不宣称已经迁完全部副作用。
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前刻意未做
|
||||
|
||||
本轮明确没有扩到以下范围:
|
||||
|
||||
1. 还没有落 `npc_trade` 的库存与价格正式结算
|
||||
2. 还没有落 `npc_gift` 的背包扣减与物品收益结算
|
||||
3. 还没有落 `npc_recruit` 的队伍替换与 companion 真相迁移
|
||||
4. `npc_fight / npc_spar` 的正式 `battle_state` 初始化编排不在 `module-npc` crate 内部完成,而是下沉到 `spacetime-module` 聚合 procedure
|
||||
5. 还没有把 `custom world` 的 `narrativeProfile / backstoryReveal` 真正投影进 SpacetimeDB
|
||||
6. 还没有把 Node 侧 `npcInteractionService` 全量切到 `server-rs`
|
||||
7. 还没有给前端接入 `SpacetimeDB` 的 NPC 订阅读模型
|
||||
|
||||
也就是说,本轮只是把 **NPC 关系状态基座** 立起来,不宣称已经完成完整 NPC 子域迁移。
|
||||
|
||||
---
|
||||
|
||||
## 6. 下一步建议
|
||||
|
||||
后续应继续按下面顺序推进:
|
||||
|
||||
1. 把 `npc_recruit` 的 companion / roster 真相迁移拆成 `module-npc + module-runtime + module-story` 的联合 reducer 设计。
|
||||
2. 在 `spacetime-client` / Axum 侧继续把 `npc_fight / npc_spar` 的 `battle_state` 联合编排接口接出来。
|
||||
3. 把 `npc_trade / npc_gift` 的正式库存、扣减与收益迁到 `inventory / runtime-item` 联动链。
|
||||
4. 把 `backstoryReveal / privateChatUnlockAffinity / narrativeProfile` 的可见性规则投成显式读模型。
|
||||
5. 再接 `api-server` 的 NPC facade 与前端 runtime action。
|
||||
Reference in New Issue
Block a user