Skip to content

工位系统 ​

EmakiCooking 七类工位的方块来源, 交互方式, 进度状态, 材料缓存, 燃料, 流体和阶段数据写在哪, 以及出问题时怎么排查, 说明如下

工位就是世界里用来做菜的那块方块. Cooking 的工位承载配方交互, 进度状态, 材料缓存, 燃料, 流体, 阶段数据和结果产出. 一个工位可以对应方块, 界面或交互实体; 排查时先确认方块来源, 再看工位状态和配方匹配

工位类型 ​

工位主要状态适合玩法
砧板当前输入, 累计数量, 切割次数切菜, 分割, 预处理
研磨机当前输入, 剩余时间磨粉, 研磨药材, 压碎矿物
蒸锅当前输入, 燃料, 水分, 蒸汽进度蒸鱼, 蒸饭, 熟制半成品
炒锅材料列表, 火候, 翻炒次数, 错误次数需要操作节奏和判定的料理
烤炉输入, 燃烧时间, 火力, 烘烤阶段需要控温和阶段判定的烘焙
榨汁机输入, 压榨次数, 流体 ID, 流体容量果汁, 饮品, 按容器分装
发酵桶多输入, 发酵进度, 是否完成, 阶段酒, 醋, 发酵半成品

配置顺序 ​

  1. 先在 config.yml 里确认工位方块来源和交互方式
  2. 再到 recipes/<station>/ 写对应工位的配方
  3. 如果工位有界面, 再调整 gui/*.yml
  4. 使用 /ec inspect hand 检查材料, 工具, 容器和方块来源
  5. 使用 /ec debug 排查工位监听, 展示实体和持久化状态

通用配置字段 ​

以下字段在 stations.<工位> 下都可用; 具体工位额外的字段见各工位小节

字段类型必填默认值取值范围说明
block_item_sourceslist<string>是发货给每类工位各一项 (见各工位小节)CoreLib 物品来源简写, 如 minecraft-oak_log这个工位对应的方块来源, 任意一项对得上就算识别成功. 这里不支持写 matcher, 原因见下方说明
interactions.<操作>string否各工位内置默认 (见下方"交互默认值")left_click, right_click, shift_left_click, shift_right_click (大小写不敏感, - 与 _ 等价)每种操作用哪个点击方式触发. 没写或值非法时回退到内置默认值; 该工位不支持的操作没有默认值
drop_resultboolean否truetrue / false结果是否直接掉到世界里, 而不是进玩家背包
only_recipe_itemsboolean否继承 input_rules.only_recipe_items (默认 true)true / false是否只允许能匹配当前工位配方的物品进入输入
disabled_worldslist<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: 1

DANGER

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_restrictionboolean否falsetrue / false是否检查空间限制
interaction_delay_msint否1000≥ 0 (毫秒)交互最小间隔, 小于 0 按 0 处理
toolobject否无子节点写出 (此时没有物品能当厨刀)含 item_sources / matcher判断哪个物品算厨刀, 两个同级字段取 AND
tool_item_sources / tool_matcher—否——tool 的旧扁平写法, 仅在没有 tool 子节点时读取
cut_damage.enabledboolean否truetrue / false切割是否可能损坏工具
cut_damage.chanceint否10≥ 0 (百分比)每次切割扣耐久的概率
cut_damage.valueint否2≥ 0命中概率时扣除的耐久值
actions.cut / actions.complete / actions.placelist<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_bowlboolean否truetrue / false是否要求手持碗才能出锅
stir_delay_msint否5000≥ 0 (毫秒)两次翻炒之间的最小间隔
timeout_msint否30000≥ 0 (毫秒)锅状态超时后按过火处理
ignite_heat_sourceboolean否truetrue / false放入食材时是否点亮下方热源外观; 锅清空后会尝试熄灭
invalid_result_item_sourceslist<string>否[minecraft-stone]物品来源简写未命中配方或结果无效时的默认产物来源, 取第一项
spatulaobject否无子节点写出 (此时没有物品能当锅铲)含 item_sources / matcher判断哪个物品算锅铲, 两个同级字段取 AND
spatula_item_sources / spatula_matcher—否——spatula 的旧扁平写法, 仅在没有 spatula 子节点时读取
heat_levels[].item_sourcesstring否—物品来源简写命中的下方热源方块来源; 缺失的条目会被跳过
heat_levels[].lit_item_sourcesstring否无 (不切换点亮外观)物品来源简写该热源点亮时替换成的方块来源
heat_levels[].unlit_item_sourcesstring否回退为同级 item_sources物品来源简写该热源熄灭时替换成的方块来源
heat_levels[].levelint否0≥ 0对应火候等级, 小于 0 按 0 处理
stir_animation.enabledboolean否truetrue / false是否播放翻炒动画
stir_animation.duration_ticksint否10≥ 2 (tick)动画总时长; 小于 2 按 2 处理. 随包提供的 config.yml 里显式写的是 20
stir_animation.heightdouble否0.4≥ 0 (格)食材抛起的高度; 随包提供的 config.yml 里显式写的是 1.0
stir_animation.rotation_axisstring否xx / y / z旋转轴, 非法值回退为 x
stir_animation.rotation_degreesdouble否360.0— (源码未校验)旋转角度 (度)
scald_damage.enabledboolean否truetrue / false是否启用烫伤
scald_damage.valueint否2≥ 0烫伤伤害值
failure.enabledboolean否truetrue / false是否启用翻炒失败产物
failure.chanceint否5≥ 0 (百分比)翻炒触发失败的概率
failure.item_sourcesstring否[minecraft-bone_meal]物品来源简写失败时产出的物品来源, 取第一项
actions.stir / actions.add_ingredient / actions.servelist<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_ticksint否20≥ 1 (tick)后台检查周期. 研磨机放入材料后自动开始, 按此间隔检查进度
actions.start / actions.running / actions.completelist<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_sourceslist<string> 或 object否[minecraft-furnace, minecraft-smoker, minecraft-blast_furnace]物品来源简写; 对象写法含 item_sources (或 source / item), lit_item_sources, unlit_item_sources蒸锅下方热源方块的来源. 对象写法可以为自定义方块指定点亮和熄灭时替换的来源; 省略 unlit_item_sources 时回退到同级来源
ignite_heat_sourceboolean否truetrue / false加燃料后是否点亮下方热源外观
fuels[].item_sourcesstring否—物品来源简写燃料允许的物品来源. 和同级的 matcher 取 AND, 两者都省略时这一条永远匹配不到
fuels[].matcherobject否无通用 matcher; 不得写物品源条件燃料的组件 / PDC / Lore 等附加条件, 见 物品匹配器
fuels[].duration_secondsint否0≥ 0 (秒)投入燃料后增加的燃烧时间. 燃料取首个命中, 条件更严的窄条目必须写在同一个物品源的宽条目之前
moisture_rules[].inputobject否无含 item_sources / matcher判断投入的是什么水; input.item_sources 与 input.matcher 取 AND, 两者都省略时这条规则永远匹配不到
moisture_rules[].input_item_sources / moisture_rules[].input_matcher—否——input 的旧扁平写法, 仅在没有 input 子节点时读取
moisture_rules[].item_sourcesstring否—物品来源简写加水后返还的空容器来源. 这是产出侧用来构造物品的字段, 不是判定位
moisture_rules[].moistureint否0≥ 0加水后增加的水分值
reset_progress_when_steam_emptyboolean否truetrue / false蒸汽耗尽时是否重置全部进度
steam_production_efficiencyint否10≥ 0每个周期最多将多少 moisture 转成 steam
steam_conversion_efficiencyint否1≥ 0每次 steam 消耗换算成多少进度
steam_consumption_efficiencyint否1≥ 0每个周期的基础 steam 消耗量
actions.fuel / actions.moisturelist<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.minint否20≥ 0火力区间下限, 低于该值暂停烤制计时
heat.maxint否80≥ heat.min火力区间上限, 高于该值暂停烤制计时; 小于下限时被抬到下限
heat.decay_per_secondint否5≥ 0 (每秒)每秒自然衰减的火力
fuels[].item_sourcesstring否—物品来源简写燃料允许的物品来源. 和同级的 matcher 取 AND, 两者都省略时这一条永远匹配不到
fuels[].matcherobject否无通用 matcher; 不得写物品源条件燃料的附加条件, 见 物品匹配器
fuels[].duration_secondsint否0≥ 0 (秒)投入燃料后增加的燃烧时间. 燃料按列表顺序取首个命中, 命中即停
fuels[].heatint否0≥ 0投入燃料后增加的火力
actions.fuellist<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_containerboolean否truetrue / false是否要求容器才能盛取结果
max_fluid_mlint否1000≥ 1 (ml)榨汁机内部默认最大流体容量
default_serving_mlint否250≥ 1 (ml)默认每次容器盛取需要的流体量; 配方 container.serving_ml 可覆盖
containerobject否无子节点写出 (此时没有物品能当容器)含 item_sources / matcher判断哪个物品算盛取容器, 两个同级字段取 AND
container_item_sources / container_matcher—否——container 的旧扁平写法, 仅在没有 container 子节点时读取
actions.press / actions.complete / actions.servelist<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_openboolean否truetrue / false打开界面时是否暂停发酵进度
only_recipe_itemsboolean否继承 input_rules.only_recipe_items (默认 true)true / false是否只允许配方材料进入输入
actions.start / actions.collectlist<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
字段类型必填默认值取值范围说明
backendstring否autoauto / packet_events / bukkit展示后端, 非法值回退为 auto. packet_events 加载失败时回退 Bukkit
view_distance_blocksdouble否48≥ 1 (方块)packet 后端可见距离
refresh_interval_ticksint否20≥ 1 (tick)packet 后端可见性刷新间隔
wok.layout_radiusdouble否0.26≥ 0 (方块)炒锅内食材展示布局半径

display_adjustments 可以按工位调整偏移, 旋转和缩放: display_adjustments.defaults.item / defaults.block 是物品型与方块型展示的全局默认值, display_adjustments.station_defaults.<工位> 用来按工位覆盖. 配自定义方块工位时, 先用默认值确认展示正常, 再微调高度和旋转

字段类型必填默认值取值范围说明
display_adjustments.defaults.item.offset.x/y/zdouble否0.5 / 1.02 / 0.5— (源码未校验)物品型展示相对工位方块的位置偏移
display_adjustments.defaults.item.rotation.x/y/zdouble 或 string否90.0 / 0.0 / 0.0度数, 或 "min-max" 范围字符串物品型展示旋转角度; 范围写法每次随机取值
display_adjustments.defaults.item.scale.x/y/zdouble否0.5 / 0.5 / 0.5— (源码未校验)物品型展示缩放
display_adjustments.defaults.block.offset.x/y/zdouble否0.5 / 1.125 / 0.5— (源码未校验)方块型展示位置偏移
display_adjustments.defaults.block.rotation.x/y/zdouble 或 string否0.0 / 90.0 / 0.0度数, 或 "min-max" 范围字符串方块型展示旋转角度
display_adjustments.defaults.block.scale.x/y/zdouble否0.25 / 0.25 / 0.25— (源码未校验)方块型展示缩放
display_adjustments.station_defaults.<工位>.<item|block>.*同上否继承对应 defaults同上按工位覆盖上述任一子字段; 未写的子字段继承全局默认

display_entities.text 控制工位运行中的文本展示实体 (结果 / 过程 / 下一步引导):

字段类型必填默认值取值范围说明
text.enabledboolean否truetrue / false是否启用文本展示实体
text.billboardstring否centerfixed / vertical / horizontal / center朝向模式, 非法值回退为 center
text.line_widthint否200≥ 1 (像素)文本最大行宽
text.backgroundint否0ARGB 整数背景色; 0 表示完全透明 (无背景框). 半透明黑示例: 1056964608
text.shadowboolean否truetrue / false是否渲染文字阴影
text.see_throughboolean否falsetrue / false是否穿墙可见
text.defaults.offset.x/y/zdouble否0.5 / 1.6 / 0.5— (源码未校验)文本相对工位方块的偏移, 省略的轴单独回退默认
text.defaults.scale.x/y/zdouble否1.0 / 1.0 / 1.0— (源码未校验)文本缩放
text.stations.<工位>.enabledboolean否truetrue / false按工位开关文本展示
text.stations.<工位>.billboardstring否继承 text.billboard同 text.billboard按工位覆盖朝向
text.stations.<工位>.offset / .scaleobject否继承 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物品来源简写是—单个物品来源匹配的物品来源. 解析出的来源简写作为该调整的键; 缺失或无法解析时整个文件被跳过
adjustmentobject否无含 offset / rotation / scale适用于所有工位的共享调整; 省略该段时, 会尝试直接从文件根读取 offset / rotation / scale
stations.<工位>object否无工位文件夹名按工位覆盖的调整, 优先级高于 adjustment
offset.x/y/zdouble否继承全局默认— (源码未校验)相对工位方块的位置偏移
rotation.x/y/zdouble 或 string否继承全局默认度数, 或 "-28.0-18.0" 这类范围写法旋转角度; 范围写法表示随机取值, min > max 会自动交换
scale.x/y/zdouble否继承全局默认— (源码未校验)缩放比例

若文件既没有共享调整也没有任何可识别的工位调整, 该文件会被跳过

炒锅调参建议 ​

stir_animation 与 scald_damage, failure 的具体字段见上方炒锅配置字段. 你把炒锅用于轻休闲玩法时, 可以关闭烫伤或降低 scald_damage.value; 用于节奏挑战时, 可以提高 failure.chance 并配合失败产物

状态生命周期 ​

  1. 玩家右键或按配置点击工位
  2. 模块检查权限, 冷却, 工位是否被占用以及手持物是否满足交互要求
  3. 打开界面或进入交互状态
  4. 玩家放入材料, 投入燃料, 注入水分, 压榨或开始发酵
  5. 工位记录进度, 例如切割次数, 研磨剩余时间, 蒸汽, 火候, 流体容量或发酵阶段
  6. 达成条件后消耗输入并生成结果; 部分工位可先进入"完成待领取"状态
  7. 执行动作并清理临时状态, 必要时保留剩余流体, 剩余燃料或剩余进度

多人和重启处理 ​

  • 同一工位不要被多个玩家同时修改同一份材料缓存
  • 如果允许协作, 需要明确谁获得产物, 谁承担材料消耗
  • 工位状态优先随方块实体 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_typestring否发货四个文件都写 CHEST容器类型名当前 Cooking 的 GUI 控制器不读取此键, 仅作声明, 改它不产生效果
titlestring否蒸锅 <dark_gray>蒸锅, 烤炉 <dark_gray>烤炉, 榨汁机 <dark_gray>榨汁机, 发酵桶 <dark_gray>发酵桶MiniMessage 文本界面标题
rowsint否蒸锅 / 烤炉 / 榨汁机 1, 发酵桶 3读取后截断到 1~6界面行数
slots.<组名>.slotslist<int>否见下方回退规则下标列表, 超出 rows × 9 的下标被忽略该组占用的槽位下标
slots.<组名>.typestring否空值按 ingredient 处理当前只实现 ingredient槽位组类型. type 非空且不等于 ingredient 的组会被整组跳过

组名本身不参与判定, 只用于分组可读性. 随包提供的文件里还写了 id, item, display_name, lore, 这些键当前不被 Cooking 读取. 若 slots 为空或全部组都被跳过, 回退为占用前 N 格 (蒸锅 / 烤炉 / 榨汁机 N=5, 发酵桶 N=7)