-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Island Planner Auto Farming & Configure
本文档介绍 Alas 岛屿计划相关任务的设计思路与配置方法。涉及的代码主要位于
module/island/(各定时任务)与 module/island_handler/(配方、商店、餐厅、规划器等公共逻辑)。
岛屿自动化由若干个独立调度的任务与一个手动工具组成:
| 任务 | 入口 | 功能 |
|---|---|---|
| 岛屿生产 IslandProduction | module/island/production.py |
收取生产槽位产物、按优先级派遣新一轮生产 |
| 岛屿订单 IslandOrder | module/island/order.py |
提交/拒绝普通、紧急、季节订单 |
| 每日补给 IslandFreebie | module/island/freebie.py |
领取每日补给,可选分享给好友 |
| 物资收集 IslandCollect | module/island/collect.py |
执行岛上物资收集 |
| 开发计划 IslandSeasonTask | module/island/season_task.py |
领取开发计划奖励、扫描未完成任务并生成需求物品 |
| 餐厅经营 IslandBusiness | module/island/business.py |
按菜单上架餐厅、安排服务员 |
| 岛屿生产规划器 IslandProductionPlanner(工具) | module/island_handler/production_planner.py |
用线性规划计算最优生产计划,生成上述任务所需配置 |
整体数据流:
岛屿科技扫描 ─┐
餐厅配置 ─────┤
开发计划需求 ─┼─> 岛屿生产规划器 (LP) ─> 每日缓冲物品 / 闲置累积物品 / 餐厅菜单
卡住的赛季订单┘ │
v
岛屿生产(补货排产) / 岛屿订单(库存保护) / 餐厅经营(上架)
规划器是整个体系的中心:它离线计算"每天应该生产什么、卖什么、买什么",
并把结果写回配置;运行时任务只按这些配置执行,不做重复计算。
纯计算部分被隔离在 ProductionPlanCalculator
(module/island_handler/production_plan_calculator.py)中,不依赖设备与配置,便于单元测试。
所有任务共享同一套库存分层语义,这是理解各配置项的关键。 对每个物品,库存从下往上分为几层:
┌────────────────────────────────────────────────┬────────────────────────────────────┐
│ 闲置累积(IdleAccumulatingItems) │ 生产线空闲时的富余产出,无上限 │
├────────────────────────────────────────────────┼────────────────────────────────────┤
│ 需求物品(TaskTarget / 卡住的赛季订单) │ 限期需求,按数量与天数折算为日速率 │
├────────────────────────────────────────────────┼────────────────────────────────────┤
│ 每日缓冲(DailyBufferItems,与手动缓冲取最大) │ 每天会被消耗的流转区间 │
├────────────────────────────────────────────────┼────────────────────────────────────┤
│ 餐厅菜单预留(由已保存菜单派生) │ 每道菜预留一整格货架容量 │
├────────────────────────────────────────────────┼────────────────────────────────────┤
│ 硬性保底(HardFloorItems) │ 用户手动占用的死库存 │
└────────────────────────────────────────────────┴────────────────────────────────────┘
生产补货目标(get_production_target_stock,module/island/utils.py):
目标库存 = 硬性保底 + 餐厅菜单预留 + 每日缓冲宽度
注意每日缓冲是区间宽度(最大值减最小值),不是绝对库存目标: 生产每天把库存补到目标值,订单、餐厅、配方消耗则把它吃回去,缓冲宽度即一天的计划消耗量。
各消耗方能动用的层级不同:
| 消耗方 | 可动用范围 |
|---|---|
| 普通订单 | 仅"目标库存"之上的部分(保护硬性保底 + 餐厅预留) |
| 紧急订单 / 季节订单 | 全部库存(优先级订单,见 get_order_effective_stock) |
| 临近服务器刷新(2 小时内)的普通订单 | 全部库存(拒单冷却约 100 分钟会超过订单剩余时间,与其过期不如强制提交) |
| 配方原料消耗(正常模式) | 硬性保底 + 餐厅预留 + 需求物品总量 之上的部分 |
| 配方原料消耗(缓冲盈余模式) | 完整目标库存(含每日缓冲) + 需求物品 之上的部分 |
这样设计的动机:
- 硬性保底给用户留出手动兑换、囤积赛季物资的空间,脚本任何行为都不会碰它。
-
餐厅预留来源于已保存的菜单:餐厅只有攒满一整格货架容量才会上架并一次性卖出,
所以每道菜按"货架容量"整格预留(
get_menu_reserve_items), 防止订单和配方把正在攒的货吃掉,也保证日销量低于货架容量的菜也能攒到可上架的数量。 - 每日缓冲是规划器计算出的"日常流转量",普通订单等日常消耗从这里出。
- 限期需求(开发计划、卡住的赛季订单)折算为每日速率注入 LP 和排产优先级,按期攒够。
规划器把"一天的岛屿运营"建成一个线性规划问题(scipy.optimize.linprog):
- 决策变量:各配方的生产批次数、商店购买次数、兑换次数、各餐厅各菜品的销量、各物品的每日净累积量。
- 目标函数:最大化净累积物品的赛季 PT 总量(即优先生产能换 PT 的物品去交订单/换积分)。
-
约束:
- 物料守恒:每个物品的产出 − 消耗 − 销售 + 野外采集/矿场/伐木场被动产出 = 净累积;
- 槽位工时:每类生产建筑(按已解锁槽位数 × 24h)的总工时上限,含地块效率加成;
- 餐厅容量:每道菜销量 ≤ 货架容量,每家餐厅总销量 ≤ 货架容量 × 货架数(由等级、服务员决定);
- 每日利润下限:金币净变化 ≥
DailyProfitLowerLimit; - 需求速率:需求物品(开发计划 + 卡住的赛季订单)的净累积 ≥ 所需日速率。
可用的配方、槽位、野外采集由岛屿科技扫描结果(存储于
IslandProductionPlanner.Storage.IslandTechnologyStatus)和当前赛季活动共同决定。
无法用当前科技生产出来的需求物品会被自动剔除(否则会让整个 LP 无解),并输出警告。
求解后导出:
-
每日缓冲物品 →
IslandProduction.DailyBufferItems:各中间产物/菜品的计划日消耗量(可乘安全余量向上取整); -
闲置累积物品 →
IslandProduction.IdleAccumulatingItems:LP 计划中每天净累积的物品及速度(扣除被动采集部分),用于闲置排产优先级; -
餐厅菜单 → 各餐厅
*Menu:LP 决定卖什么、每天卖多少; - 硬性保底物品:仅做格式规范化后写回,规划器不会替用户增删。
- 手动:在 Alas 工具页运行"岛屿生产规划器"。
- 自动:开发计划需求变化(IslandSeasonTask)或卡住的赛季订单变化(IslandOrder)时自动重算。
| 配置项 | 默认值 | 说明 |
|---|---|---|
| 本次重新扫描岛屿科技 RescanIslandTechnology | false | 科技树有变动(新解锁槽位/配方)时勾选,运行时会进游戏重扫科技树;跑完自动复位为 false。首次运行没有存档的科技状态时会自动扫描 |
| 每日利润下限 DailyProfitLowerLimit | 50000 | 每日金币净收入下限。负值表示接受亏损换 PT,0 表示收支平衡 |
| 每日缓冲安全余量 DailyBufferSafetyMargin | 0 | 导出的每日缓冲宽度乘以 (1 + 余量)。例如 0.2 表示按计划日消耗的 120% 预留,抵抗排产波动 |
| 丰壤农田效率 FieldsEfficiency | 0 | 农田收集效率加成,取值 0 / 0.04 / 0.12,参见游戏内角色收集奖励数值 |
| 坠香果园效率 OrchardEfficiency | 0 | 同上,果园 |
| 青芽苗圃效率 NurseryEfficiency | 0 | 同上,苗圃 |
矿场、伐木场的 5% 效率加成不需要配置,由科技扫描结果自动推断。
- 收取所有已完成槽位的产物(结合上次记录的完成时间,避免逐格识别);
- 对每个空闲槽位,扫描该建筑全部配方的当前库存,计算排产优先级序列并依次尝试开工;
- 记录每个槽位的完成时间,下次运行调度到最早完成的时间点。
若"每日缓冲物品"为空,任务会直接要求人工介入——必须先运行一次规划器。
每个配方按以下顺序决定是否生产、生产多少(module/island_handler/recipe.py):
- normal(正常补货):库存低于目标库存(硬性保底+餐厅预留+每日缓冲),或需求物品尚未按期攒够。 排序权重依次为:需求速率压力 > 缓冲缺口比例 > 补齐所需工时(短的优先)> 当前库存(少的优先)。 需求速率用"限期需求"折算:多个截止期取最紧的日速率,攒够即降为 0。
- buffer_surplus(缓冲盈余转化):目标库存已满,但配方原料全部是可用金币直购的商店材料 (种子、饲料、鱼苗、面粉),且原料有保护线之上的盈余时,把盈余转化为一级产物, 上限为目标库存之上再多一个缓冲宽度。此模式不会购买或兑换原料,只消化现有盈余。 配方产物的盈余不做转化——成品对订单是通用的,下游需求由正常补货维持。
-
idle_accumulating(闲置累积):以上都无事可做时,按"闲置累积物品"配置的日累积速度继续生产攒 PT。
每次派遣最多只投约 6 小时工时(
ISLAND_IDLE_ACCUMULATING_DISPATCH_HOURS), 保证槽位能较快空出来被正常补货抢占。优先累积"有效库存/日累积速度"最小(最缺)的物品。
有未满足正常需求的产物会被保护:可选模式不会把它们当原料消耗。
正常模式下原料不足时会自动处理:
- 商店材料(种子、饲料等):跳转商店购买差额;面粉需要专门进商店页购买;
- 淡水鱼肉/海水鱼肉(2521/2522):通过商店兑换补齐;
- 都不行则降低批次数,用现有原料尽量生产。
购买/兑换失败的物品会被记录,本轮不再重复尝试。
| 配置项 | 来源 | 说明 |
|---|---|---|
| 硬性保底物品 HardFloorItems | 用户手动维护 | 不可动用死库存,不会被配方、餐厅、普通订单消耗,也不作为 LP 约束 |
| 每日缓冲物品 DailyBufferItems | 规划器生成 | 预期库存区间宽度,每次规划器运行会覆写,不要手动编辑 |
| 手动缓冲物品 ManualBufferItems | 用户手动维护 | 对每日缓冲的手动补充,与每日缓冲按物品取较大值合并,不会被规划器覆写。用于给 LP 计划中没有缓冲的物品(例如只被普通订单需要的物品)在保底之上留出可消耗库存 |
| 闲置累积物品 IdleAccumulatingItems | 规划器生成 | 闲置时继续累积的物品及预期日累积速度,会被规划器覆写 |
物品映射的 YAML 格式(四项通用):
# 键可以是物品在当前服务器的名称、物品ID,或"名称 (ID)"(ID 来源见第 10 节附录)
面粉: 50
苹果 (2016): 30
2521: 20三类订单采用不同策略(详见第 2 节的库存分层):
- 紧急订单:优先处理,可消耗保底库存;库存不够时只能等待,按订单剩余时间延后重试。
- 普通订单:库存(扣除硬性保底与餐厅预留后)够则提交,不够则拒单进入冷却, 等下一单刷出来再试——普通订单可以无限刷新,拒掉换一单比等库存划算。 例外:距服务器刷新不足 2 小时的普通订单会无视保护库存强制提交,因为拒单冷却会比订单剩余时间还长。
- 季节订单:可消耗全部库存;库存不够时只能放弃,此时把该订单记为"卡住的赛季订单"。
季节订单是链式的(完成一单出下一单)。当某一单因库存不足被卡住时:
- 订单需求被识别并匹配到订单 ID,写入
StuckSeasonOrderId; - 自动触发规划器重算:该订单及其后续整条链的需求会被累加,作为 10 天期限的需求注入 LP 和排产优先级;
- 订单完成、卡住的订单消失后自动清零并再次重算。
该配置项由脚本自动维护,一般不需要手动修改;0 表示没有卡住的订单。
每次运行领取已完成任务奖励,然后扫描所有未完成任务的目标物品,
汇总写入 IslandSeasonTask.TaskTarget(需求物品)。需求发生变化时自动触发规划器重算。
TaskTarget 由扫描自动生成和维护(格式为 物品名 (ID): 数量,按 10 天期限折算日速率),
不需要手动编辑。需求会参与 LP 约束与排产优先级,攒够后自动不再占用产能。
运行时逐个检查餐厅:营业中则记录剩余时间,空闲则按保存的菜单上架菜品、按配置安排服务员开始营业。
每家餐厅(有鱼餐馆/白熊饮品/啾啾简餐/乌鱼烤肉/啾咖啡)有三组配置:
| 配置项 | 说明 |
|---|---|
| 等级 Grade | 青铜/白银/黄金/钻石。决定货架容量与货架数(青铜、白银 2 格,黄金 3 格,钻石 4 格),直接影响 LP 中的销售上限 |
| 服务员1/2 Waitress1/2 | 两个槽位无顺序。无表示空槽位,两个都为无时停用该餐厅(LP 也不会安排在此销售);任意选择管理等级最高的空闲角色;命名角色带有容量或销售加成(如肇和 +1 容量 +10% 售价),会优先选择 |
| 菜单 Menu | 由规划器生成,不要手动编辑。只销售菜单里指定的菜品;同时派生出库存保护(每道菜预留一格货架容量,见第 2 节) |
注意:修改等级或服务员后应重新运行规划器,因为销售容量和售价加成是 LP 的输入。
-
每日补给(IslandFreebie):领取每日补给。
Share(默认开)控制是否分享给好友。每日一次。 - 物资收集(IslandCollect):执行岛上物资收集,无额外配置。每日两次。
首次启用岛屿自动化:
- 配置餐厅经营:填写各餐厅等级、服务员;菜单留空(规划器会生成)。
- 配置岛屿生产规划器:填写农田/果园/苗圃效率、每日利润下限;勾选"本次重新扫描岛屿科技"。
- (可选)在岛屿生产填写硬性保底物品、手动缓冲物品。
- 在工具页运行一次岛屿生产规划器,检查日志中输出的生产/购买/销售计划是否合理。
- 启用岛屿生产、岛屿订单、餐厅经营、开发计划、每日补给、物资收集等定时任务。
日常维护:
- 解锁新科技/新槽位后:勾选"本次重新扫描岛屿科技",重跑规划器;
- 修改餐厅等级、服务员、效率加成、利润下限后:重跑规划器;
- 赛季更替后:重跑规划器(赛季活动决定部分配方与采集点的可用性);
- 开发计划需求、卡住的赛季订单变化会自动触发重算,无需手动干预。
文档和日志中出现的各类 ID(物品、配方、订单、科技、槽位等)均来自游戏客户端自带的数据表:
dev_tools/island_extractor.py 从客户端 sharecfg 目录的 lua 数据
(如 island_item_data_template.lua)中提取,生成 module/island/data.py。
感兴趣的话可以直接在该文件中按 ID 或名称查找:
| 字典 | 内容 |
|---|---|
DIC_ISLAND_ITEM |
物品:名称(cn/en/jp)、PT 值、订单售价等。配置项中的物品键即查此表 |
DIC_ISLAND_RECIPE |
生产配方:原料、产物、工时、批次上限。注意配方 ID 与其产物的物品 ID 是两套编号 |
DIC_ISLAND_SLOT / DIC_ISLAND_PRODUCTION_PLACE
|
生产槽位与建筑:槽位归属、可用配方 |
DIC_ISLAND_TECHNOLOGY |
岛屿科技树:科技扫描结果中的科技 ID 查此表 |
DIC_ISLAND_SEASON_ORDER |
赛季订单链:需求物品与后继订单,"卡住的赛季订单ID"查此表 |
DIC_ISLAND_SHOP_RECIPE / DIC_ISLAND_EXCHANGE_RECIPE
|
商店购买与兑换规则 |
DIC_ISLAND_TASK |
开发计划任务及其目标物品 |
DIC_ISLAND_SEASON / DIC_ISLAND_ACTIVITY
|
赛季时间与赛季活动(限时配方、限时采集点) |
该文件为自动生成,请勿手动修改;游戏版本更新后由维护者重新运行提取脚本刷新。
Getting Started
- Installation [EN]
- Installation [CN]
- Installation With Docker [EN]
- Emulator Support [CN]
- FAQ [EN/CN]
- FAQ [JP]
- Troubleshooting [EN]
- Another Installation guide
- Research Filter String [EN]
- Research Filter String [CN]
- Reward Shop Filter String [EN/CN]
- Island Planner Auto Farming & Configure [CN]
- Onepush Configuration [EN]
- Onepush Configuration [CN]
Development
- Perspective [CN]
- Perspective [EN]
- Debug perspective [CN]
- Debug perspective [EN]
- Item Statistics [EN]
- 1. Start
- 2.1. Debugging
- 2.2. Multi-server support
- 3.1. Utils
- 3.2. Decorators
- 3.3. Log
- 3.4. Exception
- 4.1. Detection objects
- 4.2. UI control
- 4.3. OCR
- 4.4. State loop
- 5.1. Local Map
- 5.2. Create globe Map
- 5.3. Globe Map
- 6.1. GUI Option
MISC