任务与工作
This content is not available in your language yet.
船员的一切自动行为(吃喝睡、搬运、建造、生产、操炮、救人、聊天)都由统一的任务系统驱动:系统扫描“哪里需要干活”生成任务,再按优先级把任务派给最合适的船员,高优先级任务可随时抢占低优先级任务。
任务系统参考 RimWorld / Oxygen Not Included 的架构,是整个船上模拟的中枢。它由三方角色组成:
- 发起者(Issuer):各系统的“需求探测器”。例如建造系统扫描所有未完工建筑、船员需求系统扫描每个船员的饥饿口渴值。发现需求后只“声明请求”,不直接创建任务(
ITaskIssuer.cs)。 - 任务(Task):一个具体的工作单元,由一串步骤(Step)组成,例如“走到食物→拿起→吃 2 秒→消耗”。任务在创建那一刻就预约好所需资源(物品、床位等),不依赖任何执行人独立存在(
TaskBase.cs)。 - 执行者(Consumer):船员。船员出生时注册到任务管理器(
Crew.cs),空闲时挂一个永不结束的“待机”任务(Task_Wait.cs),等待调度器派活。
玩家接触本系统的主要入口:
- 工作优先级面板(
WorkPriorityPanel.cs,见界面总览):每个船员 × 每种工作类型一个格子,左键 +1、右键 -1,范围 0(禁用)到 9(最高)。这是玩家控制“谁干什么”的唯一直接手段。 - 武器炮手分配:决定操炮/装填任务发给谁(见武器与弹药)。
- 制造队列:决定生产任务做什么配方(见生产与制作)。
- 船员头顶的任务标签与进度条会实时显示当前步骤(如“建造中”“进食中”)。
每艘船有自己独立的一套任务管理器和发起者:玩家船由 TaskIssuerRegistry.cs 在场景启动时注册 9 个全局发起者(若任务管理器未就绪,每 0.5 秒重试一次、最多 10 次);AI 船由 AIShipFactory.cs 注册同一套;社交发起者由 RelationshipManager.cs 单独注册。多船之间任务互不可见。
调度循环:每秒 5 次
Section titled “调度循环:每秒 5 次”任务管理器(TaskManager.cs)以每秒 5 次(每 0.2 秒一次)的频率执行一轮完整调度,每轮做三件事:
- 收集请求并创建任务:轮询所有发起者的请求,去重后创建任务并预约资源。
- 清理失效任务:未分配的任务若已不满足条件(目标消失、预约失效、需求已恢复),直接销毁。
- 全局贪心分配:把所有“可执行的(船员, 任务)组合”排序后逐个分配。
注意区分两种时间单位:调度循环每 0.2 秒一次;而任务一旦开始执行,其步骤逻辑每帧推进一次(代码中称 1 tick = 1 帧,按 60 帧 = 1 秒换算时长)。
任务生成:请求 → 去重 → 预约 → 任务
Section titled “任务生成:请求 → 去重 → 预约 → 任务”发起者每轮调度都会重新声明它的全部需求(无状态、幂等)。任务管理器对每条请求执行:
- 请求键去重:每条请求有唯一键(如
Eat_船员ID_Critical、Build_建筑ID)。已有同键任务存活时直接跳过,防止重复派活(TaskManager.cs的_activeRequestKeys)。 - 快速可行性筛查:低成本检查,如“全船有没有任何食物”“有没有空床位”。不通过则本轮不创建(
TaskRequest.IsBasicallyViable)。 - 创建任务并预约:查找具体资源(最近的食物、最近的煤堆),在创建任务的同时锁定预约。预约失败则不创建。预约与任务生命周期绑定,任务结束(无论成败)自动释放(
TaskBase.ReleaseReservations)。
这意味着:两个船员永远不会去拿同一块面包;建筑材料被某个搬运任务预约后,其他任务看不到这部分库存(见物品与库存)。
任务分配:全局贪心 + 抢占
Section titled “任务分配:全局贪心 + 抢占”每轮调度中,系统为每个“未分配任务 × 可执行它的船员”组合计算一个候选项,然后统一排序分配(TaskManager.AllocateTasksGlobally):
排序规则(依次比较):
- 有效优先级高者先(计算公式见下节);
- 优先级相同时,距离近者先(任务需有目标位置,否则视为无穷远);
- 距离也相同时,任务创建时间早者先。
分配为贪心式:按序遍历候选项,每轮每个船员最多领 1 个新任务、每个任务最多分给 1 人。任务一旦分给某人,立即从其他所有船员的候选列表移除。
私有任务:带“限定执行人”的任务(个人需求、操炮、社交、医生自疗)只会分给指定船员;若该船员已不存在(死亡/离船),任务直接销毁。
优先级分两层:任务层级(PriorityTier)和船员工作优先级(玩家设置),二者合成最终的有效优先级。
任务层级(PriorityTierConstants,代码常量 ConsumerPriorityConfig.cs):
| 层级值 | 含义 | 来源 |
|---|---|---|
| 0 | 禁用 | 玩家在工作面板设 0,该船员永不执行该类工作 |
| 1-9 | 普通 | 玩家可调;任务默认层级多为 5 |
| 10 | 紧急 | 系统自动(危急需求、危重维修、喂食喂水) |
| 11 | 强制 | 目前仅“全员战斗部署”状态下的炮术任务达到 11 |
有效优先级公式(ConsumerPriorityConfig.CalculateEffectivePriority):
有效优先级 = 有效船员优先级 × 100 + 工作类型内在优先级 × 10 + 技能等级(0-20 截断)
其中:有效船员优先级 = 任务层级 ≤ 5 时:玩家为该工作类型设置的值(1-9) 任务层级 > 5 时:max(任务层级, 玩家设置值) ← 系统拉高保底,但不压低玩家更高的设定玩家设置为 0(禁用)时:有效优先级 = 负无穷(永不执行)三个因子的权重设计:玩家设置差 1 级 = 差 100(主导);工作类型差 1 级 = 差 10(次要);技能差 20 级 = 差 20(仅打破平局)。
工作类型内在优先级(系统固定,玩家不可改,WorkType.cs):
| 工作类型 | 内在优先级 | 设计意图 |
|---|---|---|
| Medical 医疗 | 8 | 救人永远比干活重要 |
| Needs 需求 | 7 | 自己的吃喝拉撒 |
| Gunnery 炮手 | 6 | 战斗 |
| Command 指挥 | 5 | (暂无对应任务) |
| Construction 修建 | 4 | 建造与维修 |
| Cooking 烹饪 | 3 | |
| Crafting 制作 | 2 | |
| Preaching 布道 | 1 | (暂无对应任务) |
| Hauling 搬运 | 0 | 最低的“正经工作” |
| Social 社交 | -1 | 低于一切工作,闲时才做 |
船员的默认配置:所有工作类型优先级 = 5,社交 = 1(ConsumerPriorityConfig 构造默认值)。
举例:船员 A 把“修建”设为 5、修建技能 8。一个普通建造任务(层级 5)对他的有效优先级 = 5×100 + 4×10 + 8 = 548。一个危急进食任务(层级 10,需求类玩家设置 5)= max(10,5)×100 + 7×10 + 0 = 1070,必然抢占建造。
每轮分配时,系统也会为正在干活的船员计算候选:若新任务的有效优先级严格大于当前任务的有效优先级,则发生抢占(TaskManager.ShouldPreempt,等于不抢)。待机任务的优先级为负无穷,空闲船员见活就接。
被抢占的任务立即中断并销毁(“中断即销毁”原则,没有暂停/恢复)。但因为发起者每轮都会重新声明需求,被销毁的任务会在之后的调度轮次里重新生成、重新派人——这就是本系统的“重试”机制。
战斗状态对抢占的修正(ShipCombatState.cs,见遭遇与刷怪):
| 战斗状态 | 炮术任务层级 | 需求抢占限制 |
|---|---|---|
| Routine 日常 | 默认 5(用玩家设置) | 无 |
| Alert 警戒 | 强制拉到 8 | 无 |
| BattleStations 战斗部署 | 强制拉到 11 | 紧急模式:需求类任务不得抢占任何非需求任务(饿着也要打完仗);需求抢需求仍允许 |
战斗状态切换时,已存在的操炮/装填任务的层级会被同步刷新,不必销毁重建(GunneryTaskIssuer.OnCombatStateChanged)。
船员何时不能接任务
Section titled “船员何时不能接任务”船员的硬性资格检查(Crew.CanExecuteTask),不满足时既不会被分配、执行中也会被立即中断(执行期间每帧监控):
| 状态 | 影响 |
|---|---|
| 饿晕 / 渴晕 | 不能执行任何任务 |
| 累晕(倒地) | 不能执行任何任务(等待救援/自然恢复) |
| 重伤 | 不能执行任何任务,例外:医生的自疗任务 |
| 瘫痪(紧张鉴定失败) | 不能执行任何任务 |
| 私有任务非本人 | 不能执行 |
| 该工作类型玩家设为 0 | 不能执行 |
Step 生命周期:任务 = 步骤序列
Section titled “Step 生命周期:任务 = 步骤序列”每个任务在开始执行时生成自己的步骤序列(TaskBase.MakeNewSteps),随后每帧推进当前步骤。步骤(Step.cs)有四种完成模式:
| 完成模式 | 含义 | 典型用途 |
|---|---|---|
| Instant | 执行一次立即进入下一步 | 拾取物品、占用床位、记日志 |
| Delay | 等待固定帧数 | (框架支持,业务中多用 Never+计数替代) |
| Never | 直到自定义条件满足 | 等待 N 帧、移动到达、生产进度满 |
| PathArrival | 寻路代理到达目的地 | (框架支持) |
每个步骤可挂失败条件列表,每帧检查,任一满足则整个任务以“无法完成”收场。例如操炮步骤的失败条件是“武器失效 / 武器被禁用 / 炮手被改派”。寻路失败(目的地不可达)同样触发任务失败(Steps.Goto.cs)。
任务的五种结局(TaskEndCondition.cs):
| 结局 | 触发 | 后续 |
|---|---|---|
| Succeeded 成功 | 所有步骤跑完 | 任务移除,船员回待机 |
| Incompletable 无法完成 | 失败条件触发 / 步骤异常 / 没生成任何步骤 | 任务销毁;发起者下轮重新发请求(重试) |
| Interrupted 中断 | 被高优先级抢占 / 船员失去执行资格 | 同上 |
| Cancelled 取消 | 系统主动销毁(建筑拆除、订单取消、船员恢复) | 同上 |
| ActorDead 执行者死亡 | (枚举已定义,当前代码未显式使用) | — |
无论哪种结局,任务结束时统一执行清理(TaskBase.Cleanup):释放全部资源预约 → 停止移动 → 把手上还携带着的物品丢到脚下地面 → 按注册的逆序执行各任务自带的清理回调(如释放床位、放下背着的伤员、恢复流血计时)。船员任务被中断时还会把背包里的东西倒到地面(Crew.OnTaskInterrupt)。
失败重试的策划语义:本系统没有“任务排队等待资源”的概念。任务失败 = 销毁;只要需求还在(建筑还缺料、船员还饿着),发起者会在 0.2 秒后的下一轮调度重新声明请求,重新走“找资源→预约→派人”。唯一的节流是未分配任务的条件检查带 0.5 秒缓存(TaskBase.CanBeAssigned),所以条件变化的反应延迟最长约 0.5 秒。
耗时类工作(建造、维修、装填、铲煤、治疗)受船员能力缩放(Crew.GetWorkSpeedMultiplier):
速度倍率 = 属性修正(主属性等级) × 属性修正(技能等级) × 状态效率属性修正(level) = 0.2 × e^(0.0805 × level) (CrewAttributes.cs) level 1 → 0.22,5 → 0.30,10 → 0.45,20 → 1.0各工作类型的主属性:修建/制作/烹饪→技艺,搬运→(体能+耐力)/2,炮手→战力,医疗→认知,布道/指挥→气质。技能等级映射:烹饪复用制作技能;需求/社交无技能(按 0 计)。
状态效率(CrewStatus.GetEfficiencyMultiplier,取最小值):眩晕 0.5、力竭 0.5、醉酒 0.6、低心情 0.7,另乘欠薪惩罚倍率(见船员)。
速度倍率的实际应用举例:
- 建造/维修每帧进度 = 15 × 速度倍率(
Task_Build.cs/Task_Repair.cs的BASE_WORK_PER_TICK = 15); - 装填耗时 = 武器基础装填时间 × Lerp(1.2, 0.5, √倍率) ÷ 建筑效率(重伤建筑效率 0.5)(
Task_ReloadTurret.cs); - 治疗耗时 = 基础 5 秒(自疗 10 秒)× Lerp(1.2, 0.5, √倍率)(
Task_HealCrew.cs); - 铲煤间隔 = Lerp(2.0 秒, 0.3 秒, √倍率) ± 随机波动(
Steps.ShovelCoal.cs)。
任务类型清单(全量)
Section titled “任务类型清单(全量)”以下穷举当前游戏内全部任务类型,按工作类型分组。“层级”列为任务的 PriorityTier;执行人是否限定见“私有”列(私有 = 只能由指定船员执行)。
需求类(Needs,私有任务,发起者 CrewNeedsTaskIssuer.cs)
Section titled “需求类(Needs,私有任务,发起者 CrewNeedsTaskIssuer.cs)”需求值 0-100,越高越糟。增长速率与失能规则见船员。
| 任务 | 用途 | 触发条件(需求值) | 层级 | 步骤 | 关键数值 |
|---|---|---|---|---|---|
Task_Eat 进食 |
降低饥饿 | 饥饿 ≥ 40(普通)/ ≥ 90(危急);全船有食物 | 5 / 10 | 走到食物 → 拾取 1 个 → 进食 120 帧(约 2 秒)→ 消耗并恢复饥饿 → 记录共餐社交钩子 | 恢复量 = 物品饥饿恢复 × 新鲜度系数(物品 CSV,见物品数据表);选最近的食物源 |
Task_Drink 饮水 |
降低口渴 | 口渴 ≥ 40 / ≥ 90;全船有可饮品 | 5 / 10 | 走到水源 → 拾取 1 个 → 饮水 60 帧(约 1 秒)→ 消耗并恢复口渴 | 自动饮水按物品 DrinkPriority 升序选(-1 的物品如怪物酒不自饮);含酒精饮品累积血液酒精 |
Task_Sleep 睡眠 |
降低疲劳 | 疲劳 ≥ 90(当前仅危急睡眠自动触发) | 10(危急) | 标记入睡 →(有床则)走到床并占用 → 持续恢复疲劳 → 记录共寝钩子 | 床上恢复 2/秒,地上 1/秒;危急睡到疲劳 ≤ 20 止,普通睡到 0;无床也能就地睡 |
Task_Relieve 排泄 |
清空膀胱 | 膀胱 ≥ 40 / ≥ 90;必须有可用厕所 | 5 / 10 | 走到厕所 → 占用 → 等待 3 秒 → 膀胱清零 | 无厕所时不生成任务(憋到失禁由需求系统处理) |
医疗类(Medical,公共任务,发起者 CrewNeedsTaskIssuer.cs)
Section titled “医疗类(Medical,公共任务,发起者 CrewNeedsTaskIssuer.cs)”目标是失能船员,由其他船员执行。船员恢复或死亡时相关任务立即取消。
| 任务 | 用途 | 触发条件 | 层级 | 步骤 | 关键数值 |
|---|---|---|---|---|---|
Task_Feed 喂食 |
救饿晕者 | 目标处于“饿晕”失能;全船有食物 | 10 | 取食物 → 走到倒地者 → 喂 120 帧(约 2 秒,逐帧恢复并重置饿死倒计时)→ 消耗 | 饿晕后 10 秒不喂即死(NeedsConfig.STARVATION_DEATH_TIME) |
Task_Hydrate 喂水 |
救渴晕者 | 目标处于“渴晕”失能;全船有任何液体 | 10 | 取水 → 走到倒地者 → 喂 60 帧(约 1 秒)→ 消耗 | 救援模式可用 DrinkPriority=-1 的怪物酒兜底(灌酒也涨目标血液酒精);渴晕 10 秒不喂即死 |
Task_Rescue 救援搬运 |
把累晕者抬上床 | 目标“累晕”倒地且未躺床;有空床位 | 7 | 走到倒地者 → 抬起 → 走到床 → 放下 → 床位转占用 | 床位用被救者 ID 预约;中断时就地放下伤员 |
Task_HealCrew 治疗 |
治疗重伤者 | 目标“重伤”失能(HP ≤ 30% 进入) | 8 | 走到伤员 → 治疗(基础 5 秒 × 技能时长系数)至 HP = 上限 × 50% | 治疗期间暂停流血致死倒计时(流血 30 秒致死);医生(Surgeon 专业)可自疗,基础 10 秒,自疗任务为私有 |
医疗优先顺序的设计结果:喂食/喂水(10)> 治疗(8)> 救援搬运(7),且整个 Medical 类内在优先级最高(8),同玩家设置下永远压过其他工作。
修建类(Construction,公共任务)
Section titled “修建类(Construction,公共任务)”| 任务 | 用途 | 发起者 | 触发条件 | 层级 | 步骤 |
|---|---|---|---|---|---|
Task_Haul(建材搬运,TaskDef = FetchForConstruction) |
给工地送料 | ConstructionTaskIssuer.cs |
建筑处于框架(Frame)状态且材料未齐 | 5 | 走到最近物品源 → 拾取 → 走到工地 → 放到地面(每种缺料一条任务) |
Task_Build 建造 |
推进施工 | ConstructionTaskIssuer.cs |
框架状态 + 材料 100% + 施工进度 < 100% | 5 | 走到建筑交互点 → 持续施工(每帧 +15×速度倍率 进度点;每 10 帧复查材料,材料被偷走则任务失败)→ 完工回调 |
Task_Repair 维修 |
修复受损建筑 | RepairTaskIssuer.cs |
建筑已建成且需要维修 | 按损伤分级(下表) | 走到建筑 → 持续维修(每帧 +15×速度倍率 HP,小数累积取整)→ 修到不再需要维修 |
维修任务层级随建筑损伤动态升级(只升不降,避免修复过程中任务抖动,RepairTaskIssuer.cs):
损伤等级(HP 占比,Repairable.cs) |
维修层级 |
|---|---|
| 轻伤(70%-100% 区间内受损) | 5 |
| 中伤(HP < 70%) | 7 |
| 重伤(HP < 40%) | 9 |
| 危重(HP < 15%) | 10(紧急) |
搬运类(Hauling,公共任务)
Section titled “搬运类(Hauling,公共任务)”| 任务 | 用途 | 发起者 | 触发条件 | 层级 | 步骤 |
|---|---|---|---|---|---|
Task_SupplyBoiler 锅炉补煤 |
给锅炉送煤 | BoilerTaskIssuer.cs |
锅炉煤量 < 容量 × 70%(容量默认 50,阈值 0.7,均为 Inspector 字段) | 5 | 走到煤源 → 取煤(每趟上限 10 个,代码常量)→ 走回锅炉 → 逐个铲入(间隔 0.3-2.0 秒受技能,容器满则剩煤丢地上) |
Task_HaulToContainer(生产入料) |
给生产建筑送原料 | ProductionFetchIssuer.cs |
需船员的生产建筑当前订单缺原料,且全船存量足够补齐全部输入(防止半套料卡死) | 5 | 走到货源 → 拾取 → 走到建筑 → 校验订单仍有效 → 放入输入容器 |
Task_HaulToContainer(产出搬运) |
清空生产建筑输出 | ProductionOutputIssuer.cs |
生产建筑输出容器有可用物品 | 5 | 从输出容器取货 → 送到最近能收纳该物品的仓储容器 |
Task_HaulToContainer(买入箱卸货) |
清空交易买入箱 | PurchaseBoxOutputIssuer.cs |
买入箱(PurchaseBox)建成且有货 | 5 | 从买入箱取货 → 送到最近的木箱(WoodContainer);木箱满则任务失败 |
Task_Haul 通用搬运 |
任意点对点搬运 | (框架能力,当前仅建材搬运在用) | — | 5 | 取货 → 送达 → 放地面,送达时触发回调 |
所有搬运任务在创建时即预约源容器物品;预约失效(物品被别的途径消耗)则任务在分配前被清理。
生产类(Crafting / Cooking,公共任务,发起者 ProductionTaskIssuer.cs)
Section titled “生产类(Crafting / Cooking,公共任务,发起者 ProductionTaskIssuer.cs)”| 任务 | 用途 | 触发条件 | 层级 | 步骤 |
|---|---|---|---|---|
Task_Produce 生产 |
操作生产建筑做一轮配方 | 建筑配置“需要船员”(CSV)+ 制造队列有活跃订单 + 输入容器料齐 + 输出有空间;每建筑同时只有 1 个生产任务 | 5 | 走到建筑 → 工作“配方生产时间”秒(受建筑综合效率缩放,进度条可见;期间订单失效/缺料/输出满则失败)→ 末次校验订单 → 事务性消耗输入并产出 |
任务的工作类型由配方 CSV 的 WorkType 列决定:Cooking → 烹饪任务,Crafting → 制作任务,其余值(含空、Brewing)回落为制作。制造队列的暂停/删除/重排会立即取消对应任务。详见生产与制作。
炮术类(Gunnery,私有任务,发起者 GunneryTaskIssuer.cs)
Section titled “炮术类(Gunnery,私有任务,发起者 GunneryTaskIssuer.cs)”执行人固定为该武器分配的炮手。每武器同时只有 1 个炮术任务,操炮与装填交替进行。
| 任务 | 用途 | 触发条件 | 层级 | 步骤 |
|---|---|---|---|---|
Task_OperateTurret 操炮 |
驻守炮位索敌开火 | 武器启用 + 已分配炮手 + 弹药充足;或手动分配模式下无弹药也驻守等待 | 5 / 8 / 11(随战斗状态) | 走到炮位 → 上炮 → 循环:索敌 → 瞄准 → 开火;弹匣比例降到装填阈值以下时步骤结束 → 下炮 |
Task_ReloadTurret 装填 |
补充弹药 | 武器需要装填(弹匣比例 ≤ 装填阈值)且船上有对应弹药 | 5 / 8 / 11 | 走到弹药源 → 取弹(数量 = min(弹匣缺口, 单次装填量, 源存量))→ 走回炮位 → 装入 → 等待装填时间(基础时长 × 技能时长系数 ÷ 建筑效率) |
自动分配模式下无弹药时炮手会被释放去干别的活。弹匣容量、装填阈值、装填时长、单次装填量均来自武器配置 CSV(WeaponConsumption.cs),详见武器与弹药。
社交类(Social,私有任务,发起者 SocialIssuer.cs)
Section titled “社交类(Social,私有任务,发起者 SocialIssuer.cs)”发起者每 5 秒扫描一次(代码常量),按三档优先生成;同时进行的社交任务数上限 = max(5, 船员数 ÷ 10)。
| 触发档 | 条件 | 互动类型 |
|---|---|---|
| 冲突 | 双方互相好感均 < -20 且相邻;概率 10%/小时(按扫描间隔折算抽签,同一对 60 秒冷却) | 好感 < -50 → 辱骂,否则争吵 |
| 副手日常 | 每约 2 小时一轮(7200 秒);管理者与其副手均空闲 | 30% 深聊 / 70% 闲聊 |
| 空闲社交 | 发起者连续空闲 ≥ 60 秒,附近有空闲相邻船员 | 按好感与心情抽:深聊(好感 ≥ +20 且双方心情 > 60,25%)、讲笑话(心情 > 60 且好感 ≥ 0,20%)、八卦(好感 > +40,20%)、否则闲聊 |
| 任务 | 层级 | 步骤 | 时长与结算(Task_Socialize.cs,SocialInteractionType.cs) |
|---|---|---|---|
Task_Socialize 社交 |
1(最低,闲时才做) | 面向目标 → 双方头顶气泡 → 互动 N 秒 → 成功才结算好感 | 闲聊 3 秒 ±1 好感;深聊 6 秒 ±3;讲笑话 3 秒 ±0.5;八卦 5 秒 ±1;争吵 4 秒 双向 -2;辱骂 2 秒 目标对发起者单向 -5 |
目标船员通过“社交目标预约”锁定,防止被两人同时搭话。详见船员社交与关系。
系统 / 测试类
Section titled “系统 / 测试类”| 任务 | 用途 | 层级 |
|---|---|---|
Task_Wait 待机 |
船员空闲占位,永不自行结束,任何任务可抢占 | -999 |
TestTask |
单元测试模拟任务 | 可指定 |
TaskDef Move / MoveRandom |
已定义但当前无任何代码使用 | 5 |
公式与数值(集中表)
Section titled “公式与数值(集中表)”| 项目 | 数值 | 单位 | 来源 |
|---|---|---|---|
| 调度频率 | 每秒 5 次(每 0.2 秒一轮) | — | 代码常量 TaskManager.cs |
| 步骤推进频率 | 每帧 1 tick | 帧 | 代码 TaskBase.cs |
| 秒 → tick 换算 | 1 秒 = 60 tick(按 60 帧每秒假定) | — | 代码 Steps.Wait.cs |
| 任务可分配检查缓存 | 0.5 | 秒 | 代码常量 TaskBase.cs |
| 发起者注册重试 | 每 0.5 秒 × 最多 10 次 | — | 代码 TaskIssuerRegistry.cs |
| 项目 | 数值 | 来源 |
|---|---|---|
| 有效优先级 = 有效船员优先级×100 + 工作类型内在×10 + 技能(0-20) | — | 代码 ConsumerPriorityConfig.cs |
| 玩家可调范围 | 0(禁用)- 9 | 工作优先级面板(运行时点击) |
| 紧急 / 强制层级 | 10 / 11 | 代码常量 ConsumerPriorityConfig.cs |
| 抢占条件 | 新有效优先级 > 当前有效优先级(严格大于) | 代码 TaskManager.cs |
| 战斗状态炮术层级 | 日常 5 / 警戒 8 / 战斗部署 11 | 代码常量 ShipCombatState.cs |
| 紧急模式 | 战斗部署时需求任务不抢占非需求任务 | 代码 TaskManager.cs |
| 待机任务层级 | -999 | 代码常量 TaskDefs.cs |
需求任务触发与时长(NeedsConfig.cs,全部代码常量)
Section titled “需求任务触发与时长(NeedsConfig.cs,全部代码常量)”| 项目 | 数值 | 单位 |
|---|---|---|
| 普通进食/饮水/排泄阈值 | 需求值 ≥ 40 | 点(0-100) |
| 危急阈值(四项需求) | ≥ 90 | 点 |
| 危急需求层级 / 普通需求层级 | 10 / 5 | — |
| 进食 / 喂食时长 | 120 帧 ≈ 2 秒 | 帧 |
| 饮水 / 喂水时长 | 60 帧 ≈ 1 秒 | 帧 |
| 排泄时长 | 3 秒 | 秒 |
| 睡眠恢复速率(床 / 地) | 2 / 1 | 点每秒 |
| 危急睡眠结束阈值 | 疲劳 ≤ 20 | 点 |
| 饿晕 / 渴晕致死时间 | 10 | 秒 |
| 救援搬运层级 / 喂食喂水层级 / 治疗层级 | 7 / 10 / 8 | — |
| 重伤进入 / 退出阈值 | HP ≤ 30% / 治疗到 50% | 百分比 |
| 治疗时长(他疗 / 自疗,基础值) | 5 / 10 | 秒 |
| 流血致死时间(治疗中暂停计时) | 30 | 秒 |
工作速度与工时
Section titled “工作速度与工时”| 项目 | 数值 | 来源 |
|---|---|---|
| 属性修正公式 0.2×e^(0.0805×等级) | 等级 1→0.22,10→0.45,20→1.0 | 代码 CrewAttributes.cs |
| 速度倍率 = 属性修正×技能修正×状态效率 | 普通船员(双 5)≈0.09 | 代码 Crew.cs |
| 建造/维修基础进度 | 15 × 速度倍率 / 帧 | 代码常量 Task_Build.cs / Task_Repair.cs |
| 建造中材料复查间隔 | 每 10 帧 | 代码常量 Task_Build.cs |
| 时长类系数 Lerp(1.2, 0.5, √速度倍率) | 装填 / 治疗共用 | 代码 Task_ReloadTurret.cs / Task_HealCrew.cs |
| 铲煤间隔 Lerp(2.0, 0.3, √速度倍率) 秒 ± 波动 | 波动幅度 0.15/(1+3×倍率) | 代码 Steps.ShovelCoal.cs |
| 补煤每趟上限 | 10 个煤 | 代码常量 SupplyBoilerRequest.cs |
| 锅炉煤容量 / 补煤触发阈值 | 50 / 70% | Inspector 字段 BoilerCoalComponent.cs(锅炉 prefab) |
| 重伤建筑效率惩罚(影响装填) | ×0.5 | 代码 Repairable.cs |
生产配方表(RecipeConfig.csv,共 10 行配方,策划可直接改)
Section titled “生产配方表(RecipeConfig.csv,共 10 行配方,策划可直接改)”列含义:BuildingId 建筑、RecipeName 配方名、InputsJson/OutputsJson 输入输出、ProductionTime 生产时间(秒)、WorkType 工作类型(决定任务归类)、Description 描述。
| 建筑 | 配方 | 输入 | 输出 | 时间(秒) | 工作类型 |
|---|---|---|---|---|---|
| WaterPump | 水泵生产 | — | 水×10 | 2.0 | (自动,无需船员) |
| Boiler | 锅炉生产 | 水×10+煤×1 | 蒸汽×10+饮用水×1 | 3.0 | (自动) |
| Engine | 引擎生产 | 蒸汽×10 | 水×1 | 5.0 | (自动) |
| ButcherTable | 屠宰怪物 | 怪物尸体×1 | 怪物肉×3+兽油×2 | 5.0 | Cooking |
| Galley | 烹饪熟食 | 怪物肉×1+饮用水×1 | 熟食×1 | 4.0 | Cooking |
| AmmoBench | 制造火药 | 兽油×2+煤×1 | 火药×3 | 6.0 | Crafting |
| AmmoBench | 制造子弹 | 铁板×1+火药×1 | 子弹×10 | 5.0 | Crafting |
| AmmoBench | 铸造炮弹 | 铁板×1+火药×2 | 炮弹×5 | 8.0 | Crafting |
| Brewery | 酿怪物酒 | 怪物肉×4+饮用水×2+木材×1 | 怪物酒×1 | 8.0 | Brewing(按制作处理) |
| Brewery | 兑Grog | 怪物酒×1+饮用水×4 | Grog×4 | 2.0 | Brewing(按制作处理) |
生产建筑是否需要船员(ProductionBuildingConfig.csv,共 7 行,策划可直接改)
Section titled “生产建筑是否需要船员(ProductionBuildingConfig.csv,共 7 行,策划可直接改)”| 建筑 | 需要船员操作 |
|---|---|
| 水泵 / 锅炉 / 引擎 | 否(自动生产,不产生任务) |
| 屠宰台 / 灶台 / 军械台 / 酒坊 | 是(产生生产任务 + 入料/出料搬运任务) |
社交任务参数(SocialIssuer.cs / SocialInteractionType.cs,全部代码常量)
Section titled “社交任务参数(SocialIssuer.cs / SocialInteractionType.cs,全部代码常量)”| 项目 | 数值 |
|---|---|
| 扫描间隔 / 空闲判定 / 副手日常间隔 | 5 秒 / 60 秒 / 7200 秒 |
| 冲突概率 / 冲突对冷却 | 10% 每小时 / 60 秒 |
| 并发上限 | max(5, 船员数÷10) |
| 各互动时长 | 闲聊 3、深聊 6、笑话 3、八卦 5、争吵 4、辱骂 2(秒) |
| 好感结算 | 闲聊 +1、深聊 +3、笑话 +0.5、八卦 +1、争吵 -2(双向)、辱骂目标单向 -5 |
与其他系统的交互
Section titled “与其他系统的交互”- 船员:船员是唯一的任务执行者;需求值、失能状态、属性/技能、心情与状态效果全部反馈到任务触发与工作速度。
- 船员社交与关系:社交任务由关系系统发起,结算好感;进食/睡眠任务完成时触发共餐/共寝关系钩子。
- 物品与库存:任务创建即预约容器物品;携带、放置、消耗物品全部走容器接口;任务中断时携带物丢到地面容器。
- 修建:框架建筑触发建材搬运与建造任务;建成受损建筑触发维修任务。
- 生产与制作:制造队列驱动生产任务,入料/出料由专门搬运发起者补齐。
- 交易:买入箱到货后自动产生卸货搬运任务。
- 武器与弹药:炮手分配产生操炮/装填任务,弹匣参数决定装填触发与取弹量。
- 遭遇与刷怪 与 伤害与护甲:战斗状态拉高炮术任务优先级并抑制需求抢占;船员重伤触发治疗任务、建筑受损触发维修任务。
- 寻路与移动:所有“走到 X”步骤通过寻路代理执行,寻路失败 = 任务失败。
- 时间与调度:调度循环挂在全局 Tick 系统的每秒 5 次频道上。
- 开发者工具:船员头顶 Gizmo 显示当前任务与步骤;测试场景可注入模拟任务。
- 存档:读档后任务管理器会重建请求键去重集合(
TaskManager.RebuildActiveRequestKeys)。
配置与调参指南
Section titled “配置与调参指南”想调“谁优先干什么”:
- 玩家侧:工作优先级面板逐人逐项调 0-9(运行时,无配置文件)。
- 全局工作类型相对重要性:改
WorkType.cs的内在优先级表(程序改)。 - 各任务默认层级:
TaskDefs.cs(程序改)。 - 需求/医疗任务层级与各类阈值:
NeedsConfig.cs常量(程序改)。 - 维修分级层级:
RepairTaskIssuer.cs常量 7/9(程序改);损伤分级阈值在Repairable.cs。
想调“任务多久干完”:
- 生产时间:
Assets/StreamingAssets/RecipeConfig.csv的 ProductionTime 列(策划可改,改后用 Unity 菜单 Tools → CSV Code Generator → Generate All 重新生成代码)。 - 进食/饮水/排泄/治疗/睡眠速率:
NeedsConfig.cs与各Task_*.cs内常量(程序改)。 - 建造/维修速度基数 15:
Task_Build.cs/Task_Repair.cs(程序改)。 - 装填时长:武器配置 CSV 的 ReloadDuration / ReloadThreshold / AmmoPerReload(策划可改,见武器与弹药)。
想调“什么时候触发任务”:
- 需求触发阈值 40/90:
NeedsConfig.cs(程序改)。 - 锅炉补煤阈值与容量:锅炉 prefab 上
BoilerCoalComponent的 Inspector 字段(默认 0.7 / 50)。 - 哪些建筑需要船员生产:
ProductionBuildingConfig.csv的 RequiresCrew 列(策划可改)。 - 配方归为烹饪还是制作:
RecipeConfig.csv的 WorkType 列(策划可改,仅识别 Cooking/Crafting,其他值按制作处理)。 - 社交频率与概率:
SocialIssuer.cs常量(程序改)。
想调“战斗时的行为”:战斗状态层级 8/11 与紧急模式规则在 ShipCombatState.cs 与 TaskManager.cs(程序改)。
已知限制与注意事项
Section titled “已知限制与注意事项”- 床/厕所执行中被摧毁未处理(代码 TODO,DPP-953,
Task_Sleep.cs/Task_Relieve.cs/Task_Rescue.cs):目标建筑在任务执行中被拆/被打掉时引用会失效,可能抛异常中断任务。 - 普通睡眠未启用:任务定义里有普通睡眠(层级 5)和定时睡眠(层级 9,
SCHEDULED_SLEEP_PRIORITY),但发起者当前只在疲劳 ≥ 90 时发危急睡眠请求——船员不会“提前补觉”(CrewNeedsTaskIssuer.cs)。 - 布道(Preaching)与指挥(Command)工作类型存在但没有任何对应任务;TaskDef
Move/MoveRandom已定义未使用。 - 时长按 60 帧每秒换算:所有“N 秒”的帧计数步骤(进食、喂食等)假定 60 帧每秒,实际帧率不同会等比例偏差;治疗、生产、铲煤等用真实时间计时的步骤不受影响。
- 排泄速率常量未使用:
NeedsConfig.BLADDER_RELIEF_RATE = 10/秒已定义,但实际实现是等 3 秒后膀胱直接清零(Task_Relieve.cs)。 - 条件检查有 0.5 秒缓存:任务失效(如需求恢复、预约被释放)最长 0.5 秒后才被调度器清理。
- 中断即丢东西:任务被抢占/中断时,船员手上携带的物品和背包内容会丢到脚下地面,需要后续搬运任务收尾——高频抢占会造成地面物品散落。
- 没有任务队列:船员一次只持有一个任务,没有“做完这个再做那个”的个人队列;一切顺序由每 0.2 秒的全局重排决定。
- 玩家无直接指派:强制层级 11 目前只有战斗部署状态下的炮术任务使用,不存在“右键强制船员做某事”的指令。
- 酿酒 WorkType 回落:配方 CSV 中 Brewery 两行的 WorkType 写的是
Brewing,代码不识别该值,按制作(Crafting)处理(ProductionTaskIssuer.ResolveTaskDef)。 - 执行者死亡结局未使用:任务结束条件枚举中的 ActorDead 当前没有代码路径会触发,死亡走中断/取消路径。
- 设计文档目录
Docs/Notion/设计/基础系统/任务系统 Task System/当前只剩一个未命名 CSV,无可对照的成文设计意图;本页全部以代码实现为准。