简体中文
工位系统
EmakiCooking 七类工位的方块来源, 交互方式, 进度状态, 材料缓存, 燃料, 流体和阶段数据写在哪, 以及出问题时怎么排查, 说明如下
工位就是世界里用来做菜的那块方块. Cooking 的工位承载配方交互, 进度状态, 材料缓存, 燃料, 流体, 阶段数据和结果产出. 一个工位可以对应方块, 界面或交互实体; 排查时先确认方块来源, 再看工位状态和配方匹配
工位类型
| 工位 | 主要状态 | 适合玩法 |
|---|---|---|
| 砧板 | 当前输入, 累计数量, 切割次数 | 切菜, 分割, 预处理 |
| 研磨机 | 当前输入, 剩余时间 | 磨粉, 研磨药材, 压碎矿物 |
| 蒸锅 | 当前输入, 燃料, 水分, 蒸汽进度 | 蒸鱼, 蒸饭, 熟制半成品 |
| 炒锅 | 材料列表, 火候, 翻炒次数, 错误次数 | 需要操作节奏和判定的料理 |
| 烤炉 | 输入, 燃烧时间, 火力, 烘烤阶段 | 需要控温和阶段判定的烘焙 |
| 榨汁机 | 输入, 压榨次数, 流体 ID, 流体容量 | 果汁, 饮品, 按容器分装 |
| 发酵桶 | 多输入, 发酵进度, 是否完成, 阶段 | 酒, 醋, 发酵半成品 |
配置顺序
- 先在
config.yml里确认工位方块来源和交互方式 - 再到
recipes/<station>/写对应工位的配方 - 如果工位有界面, 再调整
gui/*.yml - 使用
/ec inspect hand检查材料, 工具, 容器和方块来源 - 使用
/ec debug排查工位监听, 展示实体和持久化状态
通用配置字段
以下字段在 stations.<工位> 下都可用; 具体工位额外的字段见各工位小节
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
block_item_sources | list<string> | 是 | 发货给每类工位各一项 (见各工位小节) | CoreLib 物品来源简写, 如 minecraft-oak_log | 这个工位对应的方块来源, 任意一项对得上就算识别成功. 这里不支持写 matcher, 原因见下方说明 |
interactions.<操作> | string | 否 | 各工位内置默认 (见下方"交互默认值") | left_click, right_click, shift_left_click, shift_right_click (大小写不敏感, - 与 _ 等价) | 每种操作用哪个点击方式触发. 没写或值非法时回退到内置默认值; 该工位不支持的操作没有默认值 |
drop_result | boolean | 否 | true | true / false | 结果是否直接掉到世界里, 而不是进玩家背包 |
only_recipe_items | boolean | 否 | 继承 input_rules.only_recipe_items (默认 true) | true / false | 是否只允许能匹配当前工位配方的物品进入输入 |
disabled_worlds | list<string> | 否 | [] (不禁用任何世界) | 世界名, 大小写不敏感 | 这个工位在哪些世界禁用. 命中后插件不接管该工位事件, 保留原版方块行为 |
actions.<操作> | list<string> | 否 | 发货对部分操作给出示例动作 | CoreLib 动作字符串 | 该操作触发时播放的反馈动作. 操作名要和 interactions 的键一致 |
交互默认值
interactions 里省略的操作使用下表内置默认值. 内置默认只覆盖该工位支持的交互
| 工位 | 默认交互 |
|---|---|
| 砧板 | place_input = shift_left_click, process = shift_left_click, return_input = right_click |
| 炒锅 | add_ingredient, stir, serve, return_ingredient = shift_left_click, inspect = shift_right_click |
| 研磨机 | start = shift_left_click |
| 蒸锅 | open = shift_right_click, fuel, moisture = right_click |
| 烤炉 | open = shift_right_click, fuel, inspect = shift_left_click |
| 榨汁机 | open = shift_right_click, process, serve = shift_left_click, inspect = right_click |
| 发酵桶 | open = shift_right_click, start, serve = shift_left_click, inspect = right_click |
工具与容器的通用物品匹配器
工位的工具, 锅铲和容器识别写在各自的子节点下, 子节点内是标准的 item_sources + matcher 两个同级字段:
| 子节点 | 作用 | 旧的扁平键 (仍兼容读取) |
|---|---|---|
stations.chopping_board.tool | 砧板工具 | tool_matcher / tool_item_sources |
stations.wok.spatula | 炒锅锅铲 | spatula_matcher / spatula_item_sources |
stations.juicer.container | 榨汁机容器 | container_matcher / container_item_sources |
TIP
子节点里 item_sources 与 matcher 取 AND: item_sources 只写允许的物品源, matcher 只写组件 / PDC / Lore 等条件. 两者都省略时这个角色就永远匹配不到物品
嵌套子节点优先. 只要写了子节点键 (如 tool), 就完全按子节点解析, 旧扁平键不再参与判定; 子节点存在但内容为空时也不会回退到扁平键
matcher 内部不能写物品源条件 (type: item_source / item_sources / source / sources 会被拒绝并告警)
旧的扁平前缀键仍被加载期兼容读取 (并在日志中告警), 不会失效, 但推荐迁移到子节点写法. 用 /ec convert-legacy 可自动迁移
yaml
stations:
chopping_board:
block_item_sources:
- minecraft-oak_log
# 既是铁斧, 又附了效率: 物品源写 item_sources, 组件条件写 matcher
tool:
item_sources:
- minecraft-iron_axe
matcher:
type: component
component: enchantments
path: efficiency
operator: '>='
value: 1DANGER
block_item_sources 不支持 matcher. 这个字段回答的是"哪个方块算这个工位", 属于方块侧识别, 不是物品输入匹配. 在那里写 matcher 不会生效
同理, 配方产出侧 (result.<branch>.outputs) 也不支持. 详见 只有输入匹配点支持 matcher
完整语法见 物品匹配器
世界黑名单
工位交互可以按世界禁用, 分全局和按工位两层, 两层都默认空列表 (不禁用任何世界):
yaml
# 全局: 对所有工位生效
station:
disabled_worlds:
- world_nether
stations:
chopping_board:
# 按工位: 只对该工位生效
disabled_worlds:
- world_the_end命中黑名单时插件不接管相关事件, 方块保持原版行为, 因此可以用它在资源世界或副本世界里保留原版交互
状态存储与 IO 优化
EmakiCooking 会按实际的工位方块选择工位状态存到哪里: 如果这个方块能提供 Bukkit TileState, 工位状态优先写进该方块实体的 PersistentDataContainer (BLOCK_PDC); 如果只是普通方块, 就回退到 data/stations/ 的 YAML 文件 (YAML_FALLBACK)
运行边界
上述后端选择, 旧 YAML 成功迁入后的备份路径, 以及发酵桶旧状态身份迁移, 当前仅由源码和本地 JVM 测试证明. 本轮没有在真实 Paper 或 Folia 服务器上实机验证, 也没有把任意旧 YAML/旧存档声明为已实机通过; 升级前请在目标服务端备份并抽样验证
这对服务器 IO 性能有直接帮助:
- 大量工位使用方块实体后, 状态随区块/方块实体保存链路持久化, 避免每个工位频繁生成和改写独立 YAML 文件
data/stations/index/<world>.idx只保存坐标, 类型, 来源和后端, 用于按区块快速定位工位, 减少重启或 ChunkLoad 时的全目录扫描- 旧 YAML 状态成功迁入方块实体 PDC 后会移到
data/stations-legacy-backup/, 出问题时便于回退排查, 也不会再被频繁读写 - 非方块实体仍然用 YAML 回退; 因此对性能敏感, 工位数量多的服务器, 建议优先把工位方块配成方块实体方块
PDC 键名
工位状态写入方块实体 PDC 时使用下列键, 命名空间为插件名 emakicooking (即完整键形如 emakicooking:station_state). 用第三方 NBT 工具排查时按这些键读取:
| 键 | 说明 |
|---|---|
station_state | 序列化后的工位状态主体 |
station_type | 工位类型 |
station_source | 工位方块来源 |
station_saved_at_ms | 最后一次保存的时间戳 (毫秒) |
station_state_version | 状态版本号, 用来判断是不是并发写入或过期写入 |
station_tombstone | 墓碑标记, 表示该位置的工位已移除 |
物品侧另有一个 PDC 键 cooking_history: 以逗号分隔记录该物品经过的配方 ID, 蒸锅链式配方的 requires_previous_step 就是靠它判定前置步骤
排查命令:
/ec inspect block: 查看准星目标方块的block_state,tile_state,storage_backend,pdc_state,indexed和legacy_yaml/ec station reindex: 重建工位坐标索引, 扫描 legacy YAML 与当前已加载区块中的 PDC 工位
Minecraft 方块实体列表 (适合做工位锚点)
下面按 Paper/Bukkit TileState 可识别的常见原版方块实体整理; 具体可用性仍以服务器版本和目标方块 tile_state=yes 为准. 同一类的木种, 颜色或变体合并展示
| 类型 | 常见方块 |
|---|---|
| 容器 | 箱子, 陷阱箱, 木桶, 潜影盒, 末影箱, 漏斗, 发射器, 投掷器, 唱片机, 讲台, 錾制书架 |
| 处理/制作 | 熔炉, 烟熏炉, 高炉, 酿造台, 营火, 灵魂营火, 合成器 |
| 展示/装饰 | 旗帜, 床, 告示牌, 悬挂告示牌, 玩家头颅, 饰纹陶罐, 蜂巢, 蜂箱 |
| 红石/功能 | 比较器, 日照探测器, 命令方块, 结构方块, 拼图方块, 移动活塞 |
| 世界/特殊 | 信标, 附魔台, 钟, 潮涌核心, 刷怪笼, 试炼刷怪笼, 宝库, 末地折跃门 |
| 幽匿/考古 | 幽匿感测体, 校频幽匿感测体, 幽匿催发体, 幽匿尖啸体, 可疑沙子, 可疑砂砾 |
| 新版本 API 暴露 | 铜傀儡雕像, 货架, 测试方块, 测试实例方块 |
砧板示例
yaml
stations:
chopping_board:
block_item_sources:
- minecraft-oak_log
only_recipe_items: true
interactions:
place_input: shift_left_click
process: shift_left_click
return_input: right_click
drop_result: true
interaction_delay_ms: 1000
tool:
item_sources:
- minecraft-iron_axe| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
space_restriction | boolean | 否 | false | true / false | 是否检查空间限制 |
interaction_delay_ms | int | 否 | 1000 | ≥ 0 (毫秒) | 交互最小间隔, 小于 0 按 0 处理 |
tool | object | 否 | 无子节点写出 (此时没有物品能当厨刀) | 含 item_sources / matcher | 判断哪个物品算厨刀, 两个同级字段取 AND |
tool_item_sources / tool_matcher | — | 否 | — | — | tool 的旧扁平写法, 仅在没有 tool 子节点时读取 |
cut_damage.enabled | boolean | 否 | true | true / false | 切割是否可能损坏工具 |
cut_damage.chance | int | 否 | 10 | ≥ 0 (百分比) | 每次切割扣耐久的概率 |
cut_damage.value | int | 否 | 2 | ≥ 0 | 命中概率时扣除的耐久值 |
actions.cut / actions.complete / actions.place | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 切割, 完成, 放入时的反馈动作 |
配方级 damage_override.chance / damage_override.value 可覆盖上面的 cut_damage 值, 详见 配方系统
砧板的输入交互会一次收下玩家主手那一整叠物品, 并在运行中累计数量; 物品展示实体仍然只显示 1 个输入物品. 配方里的 input.amount 表示每完成一轮切割需要并消耗的数量, 累计数量不足就不能开始切割. 如果配方写了 cuts_required: 1, 玩家可以对已经放入的一批食材连续切割, 不用每次重新放入一个
炒锅示例
yaml
stations:
wok:
block_item_sources:
- minecraft-iron_block
interactions:
add_ingredient: shift_left_click
stir: shift_left_click
serve: shift_left_click
return_ingredient: shift_left_click
inspect: shift_right_click
drop_result: true
need_bowl: true
stir_delay_ms: 5000
timeout_ms: 30000
spatula:
item_sources:
- minecraft-iron_shovel
heat_levels:
- item_sources:
- minecraft-campfire
level: 1
- item_sources:
- minecraft-magma_block
level: 2
- item_sources:
- minecraft-lava
level: 3炒锅配置字段
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
need_bowl | boolean | 否 | true | true / false | 是否要求手持碗才能出锅 |
stir_delay_ms | int | 否 | 5000 | ≥ 0 (毫秒) | 两次翻炒之间的最小间隔 |
timeout_ms | int | 否 | 30000 | ≥ 0 (毫秒) | 锅状态超时后按过火处理 |
ignite_heat_source | boolean | 否 | true | true / false | 放入食材时是否点亮下方热源外观; 锅清空后会尝试熄灭 |
invalid_result_item_sources | list<string> | 否 | [minecraft-stone] | 物品来源简写 | 未命中配方或结果无效时的默认产物来源, 取第一项 |
spatula | object | 否 | 无子节点写出 (此时没有物品能当锅铲) | 含 item_sources / matcher | 判断哪个物品算锅铲, 两个同级字段取 AND |
spatula_item_sources / spatula_matcher | — | 否 | — | — | spatula 的旧扁平写法, 仅在没有 spatula 子节点时读取 |
heat_levels[].item_sources | string | 否 | — | 物品来源简写 | 命中的下方热源方块来源; 缺失的条目会被跳过 |
heat_levels[].lit_item_sources | string | 否 | 无 (不切换点亮外观) | 物品来源简写 | 该热源点亮时替换成的方块来源 |
heat_levels[].unlit_item_sources | string | 否 | 回退为同级 item_sources | 物品来源简写 | 该热源熄灭时替换成的方块来源 |
heat_levels[].level | int | 否 | 0 | ≥ 0 | 对应火候等级, 小于 0 按 0 处理 |
stir_animation.enabled | boolean | 否 | true | true / false | 是否播放翻炒动画 |
stir_animation.duration_ticks | int | 否 | 10 | ≥ 2 (tick) | 动画总时长; 小于 2 按 2 处理. 随包提供的 config.yml 里显式写的是 20 |
stir_animation.height | double | 否 | 0.4 | ≥ 0 (格) | 食材抛起的高度; 随包提供的 config.yml 里显式写的是 1.0 |
stir_animation.rotation_axis | string | 否 | x | x / y / z | 旋转轴, 非法值回退为 x |
stir_animation.rotation_degrees | double | 否 | 360.0 | — (源码未校验) | 旋转角度 (度) |
scald_damage.enabled | boolean | 否 | true | true / false | 是否启用烫伤 |
scald_damage.value | int | 否 | 2 | ≥ 0 | 烫伤伤害值 |
failure.enabled | boolean | 否 | true | true / false | 是否启用翻炒失败产物 |
failure.chance | int | 否 | 5 | ≥ 0 (百分比) | 翻炒触发失败的概率 |
failure.item_sources | string | 否 | [minecraft-bone_meal] | 物品来源简写 | 失败时产出的物品来源, 取第一项 |
actions.stir / actions.add_ingredient / actions.serve | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 翻炒, 放入食材, 出锅时的反馈动作 |
炒锅的运行状态会记录材料列表, 火候, 翻炒次数和错误次数. ignite_heat_source 只影响热源方块的替换外观, 不改动配方判定
研磨机示例
yaml
stations:
grinder:
block_item_sources:
- minecraft-grindstone
interactions:
start: shift_left_click
drop_result: true
check_delay_ticks: 20
actions:
start:
- 'play_sound sound=block.grindstone.use volume=0.7 pitch=1.0'
running:
- 'spawn_particle particle=SMOKE count=2 offset_x=0.15 offset_y=0.15 offset_z=0.15'
complete:
- 'play_sound sound=entity.experience_orb.pickup volume=0.8 pitch=1.2'| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
check_delay_ticks | int | 否 | 20 | ≥ 1 (tick) | 后台检查周期. 研磨机放入材料后自动开始, 按此间隔检查进度 |
actions.start / actions.running / actions.complete | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 启动, 运行中, 完成时的反馈动作 |
研磨机是最简单的工位: 放入材料后自动开始研磨, 达到配方时间后产出结果, 不需要燃料, 水分或手动翻炒
蒸锅示例
yaml
stations:
steamer:
block_item_sources:
- minecraft-barrel
interactions:
open: shift_right_click
fuel: right_click
moisture: right_click
drop_result: true
heat_item_sources:
- minecraft-furnace
- minecraft-smoker
- minecraft-blast_furnace
ignite_heat_source: true
fuels:
- item_sources: ["minecraft-stick"]
duration_seconds: 5
- item_sources: ["minecraft-coal"]
duration_seconds: 80
moisture_rules:
# input 子节点判定投入的那一枚; 规则根部的 item_sources 是返还的空容器, 属产出侧
- input:
item_sources: ["minecraft-water_bucket"]
item_sources:
- minecraft-bucket
moisture: 120
- input:
item_sources: ["minecraft-potion"]
item_sources:
- minecraft-glass_bottle
moisture: 40
reset_progress_when_steam_empty: true
steam_production_efficiency: 10
steam_conversion_efficiency: 1
steam_consumption_efficiency: 1| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
heat_item_sources | list<string> 或 object | 否 | [minecraft-furnace, minecraft-smoker, minecraft-blast_furnace] | 物品来源简写; 对象写法含 item_sources (或 source / item), lit_item_sources, unlit_item_sources | 蒸锅下方热源方块的来源. 对象写法可以为自定义方块指定点亮和熄灭时替换的来源; 省略 unlit_item_sources 时回退到同级来源 |
ignite_heat_source | boolean | 否 | true | true / false | 加燃料后是否点亮下方热源外观 |
fuels[].item_sources | string | 否 | — | 物品来源简写 | 燃料允许的物品来源. 和同级的 matcher 取 AND, 两者都省略时这一条永远匹配不到 |
fuels[].matcher | object | 否 | 无 | 通用 matcher; 不得写物品源条件 | 燃料的组件 / PDC / Lore 等附加条件, 见 物品匹配器 |
fuels[].duration_seconds | int | 否 | 0 | ≥ 0 (秒) | 投入燃料后增加的燃烧时间. 燃料取首个命中, 条件更严的窄条目必须写在同一个物品源的宽条目之前 |
moisture_rules[].input | object | 否 | 无 | 含 item_sources / matcher | 判断投入的是什么水; input.item_sources 与 input.matcher 取 AND, 两者都省略时这条规则永远匹配不到 |
moisture_rules[].input_item_sources / moisture_rules[].input_matcher | — | 否 | — | — | input 的旧扁平写法, 仅在没有 input 子节点时读取 |
moisture_rules[].item_sources | string | 否 | — | 物品来源简写 | 加水后返还的空容器来源. 这是产出侧用来构造物品的字段, 不是判定位 |
moisture_rules[].moisture | int | 否 | 0 | ≥ 0 | 加水后增加的水分值 |
reset_progress_when_steam_empty | boolean | 否 | true | true / false | 蒸汽耗尽时是否重置全部进度 |
steam_production_efficiency | int | 否 | 10 | ≥ 0 | 每个周期最多将多少 moisture 转成 steam |
steam_conversion_efficiency | int | 否 | 1 | ≥ 0 | 每次 steam 消耗换算成多少进度 |
steam_consumption_efficiency | int | 否 | 1 | ≥ 0 | 每个周期的基础 steam 消耗量 |
actions.fuel / actions.moisture | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 加燃料, 加水分时的反馈动作 |
蒸锅的运行逻辑是: 燃料提供燃烧时间, 燃烧时把 moisture 转成 steam, steam 再推进蒸制进度. 三个 efficiency 参数控制转化速度. 水分和燃料都要玩家手动补充
烤炉示例
yaml
stations:
oven:
block_item_sources:
- minecraft-smoker
interactions:
open: shift_right_click
fuel: shift_left_click
inspect: shift_left_click
drop_result: true
heat:
min: 20
max: 80
decay_per_second: 5
fuels:
- item_sources: ["minecraft-stick"]
duration_seconds: 5
heat: 10
- item_sources: ["minecraft-coal"]
duration_seconds: 80
heat: 35| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
heat.min | int | 否 | 20 | ≥ 0 | 火力区间下限, 低于该值暂停烤制计时 |
heat.max | int | 否 | 80 | ≥ heat.min | 火力区间上限, 高于该值暂停烤制计时; 小于下限时被抬到下限 |
heat.decay_per_second | int | 否 | 5 | ≥ 0 (每秒) | 每秒自然衰减的火力 |
fuels[].item_sources | string | 否 | — | 物品来源简写 | 燃料允许的物品来源. 和同级的 matcher 取 AND, 两者都省略时这一条永远匹配不到 |
fuels[].matcher | object | 否 | 无 | 通用 matcher; 不得写物品源条件 | 燃料的附加条件, 见 物品匹配器 |
fuels[].duration_seconds | int | 否 | 0 | ≥ 0 (秒) | 投入燃料后增加的燃烧时间. 燃料按列表顺序取首个命中, 命中即停 |
fuels[].heat | int | 否 | 0 | ≥ 0 | 投入燃料后增加的火力 |
actions.fuel | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 加燃料时的反馈动作 |
fuel 与 inspect 同绑时靠手持物区分
上面的默认配置把 fuel 和 inspect 都绑到 shift_left_click, 两者靠手持物互斥消歧, 不会冲突:
- 手持物命中某条
fuels[]条目 → 走加燃料 - 手持物为空 → 走查看信息
- 手持物既不是燃料也不为空 → 两个分支都不进入
所以查看烤炉信息前要先空手
烤炉的运行状态会记录当前火力, 剩余燃烧时间, 累计烘烤时间和烘烤阶段. 火力过低或过高都会暂停正常烘烤, 配方可根据完美火力占比和过烤时间决定最终产物
榨汁机示例
yaml
stations:
juicer:
block_item_sources:
- minecraft-cauldron
interactions:
open: shift_right_click
process: shift_left_click
inspect: right_click
serve: shift_left_click
drop_result: true
only_recipe_items: true
require_container: true
max_fluid_ml: 1000
default_serving_ml: 250
container:
item_sources:
- minecraft-glass_bottle| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
require_container | boolean | 否 | true | true / false | 是否要求容器才能盛取结果 |
max_fluid_ml | int | 否 | 1000 | ≥ 1 (ml) | 榨汁机内部默认最大流体容量 |
default_serving_ml | int | 否 | 250 | ≥ 1 (ml) | 默认每次容器盛取需要的流体量; 配方 container.serving_ml 可覆盖 |
container | object | 否 | 无子节点写出 (此时没有物品能当容器) | 含 item_sources / matcher | 判断哪个物品算盛取容器, 两个同级字段取 AND |
container_item_sources / container_matcher | — | 否 | — | — | container 的旧扁平写法, 仅在没有 container 子节点时读取 |
actions.press / actions.complete / actions.serve | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 压榨, 完成, 盛取时的反馈动作 |
serve 与 process 同绑时按盛取优先级判定
上面的默认配置把 serve 和 process 都绑到 shift_left_click. 判定顺序是先看 serve 能不能优先: 工位内有流体, 且满足"不要求容器"或"手持有效盛取容器"时, 盛取优先; 两者都不满足时, 只有玩家手上也没有可压榨材料才退回盛取, 否则走压榨
因此手持容器时是盛取, 手持食材时是压榨, 同一个键位不会互相挡住
榨汁机会把压榨产物保存为"流体 ID + 容量". 同一台榨汁机同一时间只保存一种流体, 免得不同饮品混在一起. 容量达到容器所需 serving_ml 后才可盛取
发酵桶示例
yaml
stations:
fermentation_barrel:
block_item_sources:
- minecraft-barrel
interactions:
open: shift_right_click
start: shift_left_click
inspect: right_click
serve: shift_left_click
drop_result: true
pause_when_open: true
only_recipe_items: true| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
pause_when_open | boolean | 否 | true | true / false | 打开界面时是否暂停发酵进度 |
only_recipe_items | boolean | 否 | 继承 input_rules.only_recipe_items (默认 true) | true / false | 是否只允许配方材料进入输入 |
actions.start / actions.collect | list<string> | 否 | 发货给出示例 | CoreLib 动作字符串 | 开始发酵, 收取时的反馈动作 |
interactions.serve 是死键
发酵桶只分派 open, start, inspect 三个操作, serve 不参与判定 -- 默认 config.yml 里保留了这个键, 但改它不产生任何效果
收取动作由 start 绑定按当前状态分派:
- 已完成: 收取正常完成产物
- 正在发酵且处于提前收取阶段: 收取提前产物
- 其他情况: 开始发酵
想改收取键位, 要改的是 interactions.start
发酵桶适合多输入长周期配方. 配方可以定义提前收取比例, 正常完成结果和过度发酵结果
展示实体
Cooking 支持把工位输入, 半成品或结果以展示实体形式呈现在世界中. 展示实体由 display_entities 和 display_adjustments 控制
yaml
display_entities:
backend: auto
view_distance_blocks: 48
refresh_interval_ticks: 20| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
backend | string | 否 | auto | auto / packet_events / bukkit | 展示后端, 非法值回退为 auto. packet_events 加载失败时回退 Bukkit |
view_distance_blocks | double | 否 | 48 | ≥ 1 (方块) | packet 后端可见距离 |
refresh_interval_ticks | int | 否 | 20 | ≥ 1 (tick) | packet 后端可见性刷新间隔 |
wok.layout_radius | double | 否 | 0.26 | ≥ 0 (方块) | 炒锅内食材展示布局半径 |
display_adjustments 可以按工位调整偏移, 旋转和缩放: display_adjustments.defaults.item / defaults.block 是物品型与方块型展示的全局默认值, display_adjustments.station_defaults.<工位> 用来按工位覆盖. 配自定义方块工位时, 先用默认值确认展示正常, 再微调高度和旋转
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
display_adjustments.defaults.item.offset.x/y/z | double | 否 | 0.5 / 1.02 / 0.5 | — (源码未校验) | 物品型展示相对工位方块的位置偏移 |
display_adjustments.defaults.item.rotation.x/y/z | double 或 string | 否 | 90.0 / 0.0 / 0.0 | 度数, 或 "min-max" 范围字符串 | 物品型展示旋转角度; 范围写法每次随机取值 |
display_adjustments.defaults.item.scale.x/y/z | double | 否 | 0.5 / 0.5 / 0.5 | — (源码未校验) | 物品型展示缩放 |
display_adjustments.defaults.block.offset.x/y/z | double | 否 | 0.5 / 1.125 / 0.5 | — (源码未校验) | 方块型展示位置偏移 |
display_adjustments.defaults.block.rotation.x/y/z | double 或 string | 否 | 0.0 / 90.0 / 0.0 | 度数, 或 "min-max" 范围字符串 | 方块型展示旋转角度 |
display_adjustments.defaults.block.scale.x/y/z | double | 否 | 0.25 / 0.25 / 0.25 | — (源码未校验) | 方块型展示缩放 |
display_adjustments.station_defaults.<工位>.<item|block>.* | 同上 | 否 | 继承对应 defaults | 同上 | 按工位覆盖上述任一子字段; 未写的子字段继承全局默认 |
display_entities.text 控制工位运行中的文本展示实体 (结果 / 过程 / 下一步引导):
| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
text.enabled | boolean | 否 | true | true / false | 是否启用文本展示实体 |
text.billboard | string | 否 | center | fixed / vertical / horizontal / center | 朝向模式, 非法值回退为 center |
text.line_width | int | 否 | 200 | ≥ 1 (像素) | 文本最大行宽 |
text.background | int | 否 | 0 | ARGB 整数 | 背景色; 0 表示完全透明 (无背景框). 半透明黑示例: 1056964608 |
text.shadow | boolean | 否 | true | true / false | 是否渲染文字阴影 |
text.see_through | boolean | 否 | false | true / false | 是否穿墙可见 |
text.defaults.offset.x/y/z | double | 否 | 0.5 / 1.6 / 0.5 | — (源码未校验) | 文本相对工位方块的偏移, 省略的轴单独回退默认 |
text.defaults.scale.x/y/z | double | 否 | 1.0 / 1.0 / 1.0 | — (源码未校验) | 文本缩放 |
text.stations.<工位>.enabled | boolean | 否 | true | true / false | 按工位开关文本展示 |
text.stations.<工位>.billboard | string | 否 | 继承 text.billboard | 同 text.billboard | 按工位覆盖朝向 |
text.stations.<工位>.offset / .scale | object | 否 | 继承 text.defaults | 同 text.defaults | 按工位覆盖偏移与缩放 |
物品展示调整
item_adjustments/ 目录用于给特定物品在特定工位上单独设置展示参数. 文件名不参与匹配, 实际以文件内 item_sources 解析出的来源为准; 同一来源只保留最后加载的一份
yaml
item_sources:
- "minecraft-carrot"
stations:
chopping_board:
offset:
x: 0.54
y: 1.01
z: 0.52
rotation:
x: 90.0
y: 0.0
z: 24.0
scale:
x: 0.72
y: 0.72
z: 0.72
wok:
offset:
x: 0.47
y: 1.0
z: 0.45
rotation:
x: 88.0
y: 12.0
z: "-28.0-18.0"
scale:
x: 0.56
y: 0.56
z: 0.56| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
item_sources | 物品来源简写 | 是 | — | 单个物品来源 | 匹配的物品来源. 解析出的来源简写作为该调整的键; 缺失或无法解析时整个文件被跳过 |
adjustment | object | 否 | 无 | 含 offset / rotation / scale | 适用于所有工位的共享调整; 省略该段时, 会尝试直接从文件根读取 offset / rotation / scale |
stations.<工位> | object | 否 | 无 | 工位文件夹名 | 按工位覆盖的调整, 优先级高于 adjustment |
offset.x/y/z | double | 否 | 继承全局默认 | — (源码未校验) | 相对工位方块的位置偏移 |
rotation.x/y/z | double 或 string | 否 | 继承全局默认 | 度数, 或 "-28.0-18.0" 这类范围写法 | 旋转角度; 范围写法表示随机取值, min > max 会自动交换 |
scale.x/y/z | double | 否 | 继承全局默认 | — (源码未校验) | 缩放比例 |
若文件既没有共享调整也没有任何可识别的工位调整, 该文件会被跳过
炒锅调参建议
stir_animation 与 scald_damage, failure 的具体字段见上方炒锅配置字段. 你把炒锅用于轻休闲玩法时, 可以关闭烫伤或降低 scald_damage.value; 用于节奏挑战时, 可以提高 failure.chance 并配合失败产物
状态生命周期
- 玩家右键或按配置点击工位
- 模块检查权限, 冷却, 工位是否被占用以及手持物是否满足交互要求
- 打开界面或进入交互状态
- 玩家放入材料, 投入燃料, 注入水分, 压榨或开始发酵
- 工位记录进度, 例如切割次数, 研磨剩余时间, 蒸汽, 火候, 流体容量或发酵阶段
- 达成条件后消耗输入并生成结果; 部分工位可先进入"完成待领取"状态
- 执行动作并清理临时状态, 必要时保留剩余流体, 剩余燃料或剩余进度
多人和重启处理
- 同一工位不要被多个玩家同时修改同一份材料缓存
- 如果允许协作, 需要明确谁获得产物, 谁承担材料消耗
- 工位状态优先随方块实体 PDC 持久化, 普通方块使用
data/stations/的 YAML 回退 data/stations/index/<world>.idx记录坐标与后端, ChunkLoad 时按索引恢复容器内容, 进度和展示状态, ChunkUnload 时卸载运行中的缓存- 若直接删除或替换方块实体, 索引可能仍指向旧的 PDC 工位; 用
/ec inspect block判断 backend/PDC, 再用/ec station reindex重建索引 - 对榨汁机, 烤炉和发酵桶, 额外确认流体容量, 烘烤阶段和发酵进度能正确序列化
工位权限
各工位的操作权限节点, 默认持有者与说明集中在 命令与权限; paper-plugin.yml 中这些节点默认全部为 true
配方还可以通过自身的 permission 字段单独限制使用者, 见 配方系统
GUI 覆盖范围
| 工位 | 是否有 GUI |
|---|---|
| 蒸锅 | 有 |
| 烤炉 | 有 |
| 榨汁机 | 有 |
| 发酵桶 | 有 |
| 砧板 | 无 (直接交互) |
| 研磨机 | 无 (直接交互) |
| 炒锅 | 无 (直接交互) |
GUI 配置结构
四个有 GUI 的工位各对应 gui/ 下的一个文件: gui/steamer.yml, gui/oven.yml, gui/juicer.yml, gui/fermentation_barrel.yml
yaml
gui_type: CHEST
title: "<dark_gray>蒸锅"
rows: 1
slots:
ingredient_slots:
slots:
- 0
- 1
- 2
- 3
- 4
type: "ingredient"| 字段 | 类型 | 必填 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|---|
gui_type | string | 否 | 发货四个文件都写 CHEST | 容器类型名 | 当前 Cooking 的 GUI 控制器不读取此键, 仅作声明, 改它不产生效果 |
title | string | 否 | 蒸锅 <dark_gray>蒸锅, 烤炉 <dark_gray>烤炉, 榨汁机 <dark_gray>榨汁机, 发酵桶 <dark_gray>发酵桶 | MiniMessage 文本 | 界面标题 |
rows | int | 否 | 蒸锅 / 烤炉 / 榨汁机 1, 发酵桶 3 | 读取后截断到 1~6 | 界面行数 |
slots.<组名>.slots | list<int> | 否 | 见下方回退规则 | 下标列表, 超出 rows × 9 的下标被忽略 | 该组占用的槽位下标 |
slots.<组名>.type | string | 否 | 空值按 ingredient 处理 | 当前只实现 ingredient | 槽位组类型. type 非空且不等于 ingredient 的组会被整组跳过 |
组名本身不参与判定, 只用于分组可读性. 随包提供的文件里还写了 id, item, display_name, lore, 这些键当前不被 Cooking 读取. 若 slots 为空或全部组都被跳过, 回退为占用前 N 格 (蒸锅 / 烤炉 / 榨汁机 N=5, 发酵桶 N=7)