diff options
| -rw-r--r-- | docs/design/profession-system.md | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/docs/design/profession-system.md b/docs/design/profession-system.md new file mode 100644 index 0000000..856a4c9 --- /dev/null +++ b/docs/design/profession-system.md @@ -0,0 +1,92 @@ +# 职业系统设计(profession-system) + +状态:**P37 首切片设计稿(先设计后实现)**。本文件是用户三大可玩性方向 #3(开局职业选择 → +职业影响剧情与每日任务)的设计与验收依据。首切片沿用已落地的四项职业,不新增运行时机制、 +不改 `Sim.step` 数值路径、不改地图/世界生成 seed 口径。 + +## 0. 一句话概述 + +开局在新游戏后选一名职业;职业只在**开局一次性**写入玩家侧的钱/体力/物品,并决定**当日任务 +模板池**与**村民对话回应的小幅偏向**。世界(地图、NPC、谣言、关系)生成完全不受职业影响, +因此同一 seed 不同职业得到的是同一个世界、同一个 NPC 布局,只有玩家侧与任务/对话不同。 + +## 1. 职业列表 + +首切片 4 个(普通中文,无称号式标签):**农夫、渔夫、货郎、书生**;另有「暂不选择」表示不带职业 +(等同旧行为)。匠人/船匠等留待后续单,本单不做。 + +### 1.1 开局属性差异(钱 / 体力 / 物品) + +| 职业 | 开局钱 | 开局体力 | 开局物品 | +|---|---|---|---| +| 农夫 | 60 | 100 | 粮食 ×12 | +| 渔夫 | 45 | 95 | 粮食 ×8、鱼 ×3 | +| 货郎 | 90 | 100 | 粮食 ×6、香辛料 ×4 | +| 书生 | 70 | 100 | 粮食 ×10、卷轴 ×2 | +| 暂不选择 | 沿用世界默认 | 沿用世界默认 | 沿用世界默认 | + +- 差异在**开局建世界时一次性写入**玩家 `Needs`(钱/体力)与职业档案(物品清单);此后 `Sim.step` + 的数值演化对职业零感知。 +- 「暂不选择」与旧存档(无职业)走同一条默认路径,数值与旧版逐位一致。 + +### 1.2 对每日任务的影响(生成规则的变化点) + +- **模板池按职业分化**,当日任务在池内确定性抽一条: + + | 职业 | 任务池(模板) | + |---|---| + | 农夫 | 送粮、帮工、翻土 | + | 渔夫 | 夜捕、卖渔、询价 | + | 货郎 | 收货、转卖 | + | 书生 | 观察记事、论理 | + | 暂不选择 | 无当日任务 | + +- **确定性**:当日任务 = `hash(seed ⊕ 职业种子, 第几天) mod 池大小`,与 `Rng.fs` 的 splitmix 同源, + 禁用 `System.Random`。同一 (seed, 职业, 天) 必然得到同一条任务,跨进程/跨机可复现。 +- **变化点**:池内容随职业变化;任务窗口覆盖整天(当日 00:00 到当日结束),逾期判失败; + 完成后写年鉴,走既有事件通道(对话/交易/到达瓦片/观察),不新增状态机。 + +### 1.3 对剧情/对话线的影响(与现有村民对话系统的一个接点) + +- **对话接点**:村民对玩家的回应在既有「性格 → 回应」纯函数之上按职业做**确定性小幅重映射** + (只作用于单个意图,其余原样): + - 农夫 · 求助:原本会「拒绝」→ 改为「乐于助人」; + - 渔夫 · 闲聊:原本「保留」→ 改为「友好」; + - 货郎 · 闲聊:原本「保留」→ 改为「讨价还价」; + - 书生 · 讲笑话:一律改为「保留」(读过书的人讲笑话,众人反而拘谨,作为反差叙事)。 +- **剧情线**:每职业一条三段式轻剧情线(接任务 → 走访 → 收束),靠**玩家对话**推进,产物只有 + 「阶段推进 + 年鉴摘要」;结局分档由玩家与村民的关系均值决定(热络/平常/淡漠),无过场、无随机。 +- **交易接点**:货郎买卖双向小幅有利、书生解读行情小幅有利(以 4 位定点整数基点表达,钳在 + ±5% 内);农夫/渔夫/无职业恒为 1.0,与旧行为逐位一致。 + +## 2. 数据与确定性约束(硬要求) + +- 职业选择**不改变地图/世界生成的 seed 确定性**:世界仍只由 seed 决定;职业在玩家侧孤立。 +- 任务/剧情/对话/报价全部是**纯函数**,输入只有 (seed, 职业, tick, 现有世界状态),无随机、无时钟依赖。 +- 存档兼容:旧存档(v1/v2,无职业字段)读入即「暂不选择」,行为与旧版一致,不吞档。 + +## 3. 明确不做(留给后续单) + +- 不做全村 NPC 职业化(职业只挂在玩家侧)。 +- 不做技能树/等级/装备/数值化剧情树。 +- 不做匠人/船匠等其他职业(本单仅 4 个)。 +- 不改 `Sim.step` 数值路径、不改 `performance-baseline` 的 digest 口径。 +- 不新增付费/凭据/权限相关字段;不引入任何「入排/募招/试验分组」类字段(本项目非临床试验)。 + +## 4. 验收条件 + +可测条目(对应自动化用例,均走 Kernel/Sim 纯函数口径优先): + +1. **渔夫首项钓鱼相关**:选渔夫开局(seed=42),开局当日任务 ∈ {夜捕, 卖渔, 询价},且 + `taskNameOf` 为「夜捕/卖渔/询价」之一。 +2. **职业确定性任务生成**:同一 (seed, 职业) 下,第 0..N 天的任务序列两次计算逐项相等; + 不同职业的任务序列至少有一天不同,且每天任务都在该职业池内。 +3. **开局属性差异**:农夫/渔夫/货郎/书生的开局钱分别为 60/45/90/70,渔夫体力 95、其余 100; + 开局物品清单按 §1.1 各不同;「暂不选择」沿用默认值。 +4. **旧存档兼容**:v1/v2 存档读入后职业为「无」;不带职业的 v2 写回逐字节不变。 +5. **中文 UI 选择**:主菜单「选择职业」页可用键盘上下选择、Enter 确认;选项文案 + 「农夫/渔夫/货郎/书生/暂不选择」与标题「选择职业」均有 CJK 字形、可渲染、无缺字。 +6. **确定性不回归**:全量 Release 构建 0 警告 0 错误;全量测试通过;`--performance-baseline` + 三次 `final_digest` 恒定。 +7. **证据**:实际运行截图 `docs/evidence/p37-*.png`(职业选择页中文可读;选渔夫开局后的 HUD/任务 + 列表体现差异),且 `check-no-white-blocks.py` 无白块命中。 |
