Files
SectSimulator/doc/design/弟子系统设计.md
T
Admin cfebb8dded feat: 资质概率按难度配置化,新增普通/困难两档权重
- game_config.cfg 新增 difficulty 档位与 [recruitment_normal]/[recruitment_hard] 权重表
- GameConfig 解析各档权重,get_aptitude_weights() 按当前难度返回
- DiscipleManager 资质判定改读配置权重,删除代码常量
- 设计文档补充配置写法说明(VariantParser 数组字面量陷阱)
- 计划表同步 D3 进度
2026-08-06 00:31:02 +08:00

202 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 弟子系统设计(D3:生成 + 入宗分流)
> 对应开发计划表 D3(8/5)。本文档只描述设计,不包含代码。
> 状态:设计稿,待审阅通过后实现
---
## 一、数据模型(Disciple
弟子用一条数据记录表示,不挂在场景树上。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | int | 唯一编号,由 DiscipleManager 自增分配 |
| `name` | String | 随机生成的姓名 |
| `age` | int | 入宗年龄(12~18 |
| `aptitude` | 枚举 Aptitude | 资质(入宗分流结果) |
| `roots` | 枚举数组 SpiritRoot | 灵根列表(普通弟子 1~3 根,互不重复) |
| `is_heavenly` | bool | 天灵根标记(稀有灵根,见枚举二) |
| `realm_index` | int | 大境界索引(0=练气),D5 修炼系统推进 |
| `sub_realm_index` | int | 小境界索引(练气层数-1),D5 修炼系统推进 |
### 枚举一:资质四类(Aptitude
| 值 | 名称 | 修炼速度倍率 | 说明 |
|----|------|-------------|------|
| 0 | 下品 | 0.6x | 根基平庸 |
| 1 | 中品 | 1.0x | 资质平平 |
| 2 | 上品 | 1.5x | 天赋尚可 |
| 3 | 天骄 | 2.0x | 万中无一 |
> 倍率由 D5 修炼循环使用,此处只定义不消费。
### 枚举二:灵根五行(SpiritRoot
金、木、水、火、土 五种。灵根数量影响修炼速度(根数越少越快),元素种类影响日后生产效率匹配(D6 建筑/职能系统使用),此处只生成不消费。
### 特殊灵根:天灵根
稀有灵根,独立于五行枚举之外,用 `is_heavenly` 标记:
| 项目 | 设定 |
|------|------|
| 生成概率 | 3%(远低于四类资质中"天骄"的 5%,天灵根可叠加于任意资质之上) |
| 灵根构成 | 仅一系灵根(五行之一),纯净单灵根 |
| 修炼速度 | 在资质倍率基础上**额外 +50%**(乘法叠加,D5 修炼循环消费) |
| 地位 | 宗门争抢的种子弟子,日后可挂靠特殊培养事件(W8 预留) |
> 天灵根与资质是两个独立维度:资质定天赋底子,天灵根是稀缺加成,二者随机独立。
### 境界字段说明
新弟子统一为练气一层(realm_index=0, sub_realm_index=0)。境界显示文本规则:
- 练气期:练气 N 层
- 筑基及以上:大境界 + 初/中/后/圆满
境界的成长、突破门槛、寿元计算全部留给 D5 修炼循环,D3 只负责初始状态。
---
## 二、生成规则(随机性)
### 1. 姓名
- 姓氏池:24 个常用修仙风单姓(林、苏、叶、萧、顾、沈、楚、白……)
- 名用字池:24 个(清、玄、墨、尘、风、澜、霜、珏……)
- 规则:随机 1 个姓 + 1~2 个字(50% 概率双字名)
- 不保证唯一(同名弟子可共存,以 id 区分)
### 2. 年龄
12~18 岁均匀随机。寿元消耗、大限判断留给 D5。
### 3. 灵根
- 普通弟子:数量 1~3 根均匀随机,元素从五行中随机抽取、互不重复
- 天灵根:3% 概率判定为天灵根,灵根数量固定 1 根,修炼速度额外 +50%
- 含义:单灵根修炼最快,三灵根最慢(对应修仙世界观)
### 4. 资质(入宗分流)
按权重表掷骰,权重**随难度档位变化**(配置驱动):
| 难度 | 下品 | 中品 | 上品 | 天骄 |
|------|------|------|------|------|
| 普通(normal | 45 | 35 | 15 | 5 |
| 困难(hard | 60 | 30 | 8 | 2 |
- 当前难度由配置 `[recruitment] difficulty` 指定("normal"/"hard"
- 权重表在 `[recruitment_normal]` / `[recruitment_hard]` 节,INI 数组字面量写法:`aptitude_weights=[45, 35, 15, 5]`
- 改配置即调难度,后续可加更多档位(代码字典加一项 + 配置加一节)
---
## 三、入宗分流
"入宗分流"的含义:**按资质将弟子分为四类**,这是生成时的一次性判定,不是持续运行的机制。四类资质弟子日后可能享受不同的培养路线(D4+ 扩展),本期只完成分类本身。
### 招募机制:定时弹窗招募
招募**不是玩家随时点按钮**,而是"生成候选 → 暂停时间 → 弹窗选择":
- **开局招募**:新游戏开始,生成 **5 名候选**,暂停时间弹窗,**必须选满 3 名**才能确定
- **定期招募**:每满间隔(配置文件 `recruit_interval_years`,默认 0.1 年 = 36 天)生成 **3 名候选**,暂停时间弹窗
- **选择方式**:每个候选独立勾选"入宗",可全部接受、可全部拒绝(定期招募可 0~3 个)
- **结算**:点"确定" → 勾选的入宗、未勾选的拒绝 → 关闭弹窗 → **恢复时间**
- 所有参数(候选数、必选数、间隔)来自 `resources/game_config.cfg`,改配置即改难度
### 招募流程(文字时序)
1. 开局(MainGame 调用 `start_new_game()`)或倒计时归零(`_on_day_passed`
2. 生成候选弟子(先判天灵根 3% → 生成灵根 → 按权重掷资质 → 组名字),进入候选池
3. `applicants_generated(is_opening)` 信号发出 → 弹窗显示候选列表
4. 玩家勾选(开局模式:确定按钮在选满 3 名前禁用)
5. 点"确定" → `finish_recruitment(selected)` 结算 → 恢复时间
6. 控制台打印每位入宗弟子完整信息(姓名/年龄/资质/灵根/境界)—— 本期验收方式
---
## 四、DiscipleManager 接口
| 接口 | 签名 | 说明 |
|------|------|------|
| `start_new_game()` | 无 | 清空全部数据 → 开局候选(配置数量)→ 暂停时间 |
| `generate_applicants(count, is_opening)` | 返回无 | 清空候选池 → 生成 count 名候选 → 发信号 |
| `accept_applicant(d)` | 入参候选 | 分配 ID,候选池 → 名录,发信号,控制台打印 |
| `reject_applicant(d)` | 入参候选 | 从候选池移除 |
| `finish_recruitment(selected)` | 入参选中列表 | 结算:selected 内的入宗,其余全部拒绝 |
| `remove_disciple(d)` | 入参弟子 | 移出名录(逐出/陨落) |
| `reset()` | 无 | 清空名录与候选池、ID 与倒计时复位 |
| 信号 `disciples_changed` | 无参数 | 名录增删/重置时发出 |
| 信号 `applicants_generated(is_opening)` | bool | 候选生成时发出(弹窗监听) |
内部私有方法(不对外):生成姓名、生成灵根(含天灵根判定)、掷资质、创建候选、间隔换算。
内部定时机制:
- 字段 `_days_until_recruit`:距下次定期招募的剩余游戏天数
- 间隔 = `GameConfig.recruit_interval_years` × 360 天(TimeSystem 常量换算)
- 监听 `TimeSystem.day_passed`,每日减 1,归零 → 生成候选 → `TimeSystem.set_paused(true)`(弹窗期间时间冻结)
存放位置:`src/Character/`(与数据模型同目录),注册为 Autoload 单例,供全局访问。
## 四·五、配置系统(GameConfig
所有可调参数集中在 `resources/game_config.cfg`,由 `src/Core/GameConfig.gd`Autoload,声明在 DiscipleManager 之前)启动时读取,缺项回退代码默认值。
```ini
[recruitment]
difficulty="normal" ; 当前难度档位
opening_applicant_count=5 ; 开局候选人数
opening_pick_count=3 ; 开局必须选满数
recruit_interval_years=0.1 ; 定期招募间隔(游戏年)
recruit_applicant_count=3 ; 定期弹窗候选人数
[recruitment_normal] ; 普通难度资质权重(下品/中品/上品/天骄)
aptitude_weights=[45, 35, 15, 5]
[recruitment_hard] ; 困难难度资质权重
aptitude_weights=[60, 30, 8, 2]
```
> 注意:ConfigFile 用 VariantParser 解析值,**数组必须写 `[45, 35, 15, 5]` 字面量**,字符串值必须加引号(如 `difficulty="normal"`);裸写 `45,35,15,5` 会被截断为 45 并破坏后续节解析。
> 以后所有可调参数(天赋权重、价格、境界门槛等)统一加到这里。
---
## 五、UI 接入点
- **RecruitPanel**`src/UI/Panels/RecruitPanel/`):弹窗场景,挂在 MainGame 下(默认隐藏)
- 监听 `applicants_generated` 信号自动弹出
- 每个候选一行:姓名/年龄/资质(天灵根标记)/灵根/境界 + "入宗"勾选框
- 底部:全部接受 / 全部拒绝 / 确定
- 开局模式确定按钮在选满 3 名前禁用;确定后关闭弹窗并恢复时间
- 名录的可视化列表属于 D4(弟子列表 UI),届时由 `disciples_changed` 信号驱动
---
## 六、与后续任务衔接
| 后续任务 | 衔接方式 |
|----------|----------|
| D4 弟子列表 UI | 监听 `disciples_changed` 信号 + 遍历 `disciples` 数组 |
| D5 修炼循环 | 消费 `aptitude` 倍率与 `realm_index/sub_realm_index` 字段 |
| D6 建筑/职能系统 | 消费 `roots` 元素与生产效率匹配 |
| D8 存档接入 | Disciple 数据模型为纯数据,可直接序列化 |
---
## 七、验收清单(D3 交付标准)
- [ ] 项目能正常启动,无脚本报错
- [ ] **开局**:进入游戏即暂停,弹出"弟子入宗(开局招募)",显示 5 名候选
- [ ] 开局模式确定按钮在选满 3 名前不可用;选满后可确定
- [ ] 确定后:勾选的 3 名入宗(控制台打印),时间恢复推进
- [ ] **定期**:每 36 游戏日(0.1 年 @1x ≈ 18 秒)再次暂停弹窗,显示 3 名候选
- [ ] 定期模式可勾选 0~3 名,全部拒绝也可确定;时间正常恢复
- [ ] 多次招募后能观察到天灵根弟子(约 3% 概率,弹窗/控制台有标记)
- [ ] 修改 `game_config.cfg``opening_applicant_count` 等参数,重启后开局候选数随之变化
- [ ] 返回主菜单再进入,名录已清空(reset 生效)