# 职业系统设计(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` 无白块命中。