blob: 856a4c9a76cee1e616c5970cb92d26bfedfe813c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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` 无白块命中。
|