Skip to content

Runtime Value(运行时值) ​

Since 21.1.1

机器定义由从它放置出来的每一台机器共享。runtime value 是对定义上某一项设置的、只属于单台机器的覆盖:这一台粉碎机的 tier、这一个罐子的 auto IO 面、这一块电池的传输速率。

不需要事先声明什么。每一项可覆盖的设置都已经有一个槽位;在有东西写入之前,机器读到的仍然是定义里的值。

一个槽位存什么 ​

一个叶子值——布尔、数字、枚举、字符串列表、包围盒。auto IO 这类复合设置是一组叶子槽位,所以覆盖其中一面,其余五面仍然读定义。

行为说明
回退没有覆盖时读定义里创作的值
持久化随方块实体存盘
同步从不在两端之间传输,见下
开销零带宽;不参与每 tick 的脏值扫描
未知键本版本不认识的键会原样保留并写回

仅服务端

覆盖从不同步。没有写过任何值的客户端读到的是定义值,也就是这套系统出现之前它给出的同一个答案。客户端侧写入对客户端专属的值(渲染开关)是合理的,但它只存活到那个客户端方块实体被丢弃为止——区块重载就没了。

需要显示覆盖值的 UI(auto IO 面板就是)必须改为通过机器的 @DescSynced 自定义数据发布。

机器上的槽位 ​

键类型覆盖
machine_levelint机器 tier
drop_machine_itembool破坏时是否掉落机器物品
signal_connection.{front,back,left,right,top,bottom}bool各面红石连接
part.can_sharebool该部件能否被多个控制器共用
recipe_logic.enablebool配方逻辑是否运行
recipe_logic.dampingint每个等待 tick 损失的进度
recipe_logic.always_searchbool每次配方结束后重新搜索
recipe_logic.always_modifybool每轮重新应用修饰器
recipe_logic.consume_inputs_after_workingbool把输入消耗推迟到完成时
multiblock.show_ui_when_click_structurebool仅多方块控制器

Trait 上的槽位 ​

每个 Trait 都带配方 handler 三件套;支持的 Trait 还带 capability IO 和 auto IO:

键类型出现在
recipe_handler_ioIO所有配方 capability Trait
distinctbool同上
slot_names字符串列表同上
capability_io.{internal,front,back,left,right,top,bottom}IO暴露方块 capability 的 Trait
auto_io.{enable,front,back,left,right,top,bottom,interval}bool / IO / int支持 auto IO 的 Trait
auto_world_input.{enable,range,interval,speed}bool / 包围盒 / int物品与流体 Trait
auto_world_output.{enable,range,interval,speed}同上同上

另外还有各 Trait 自己的设置:

Trait键
item_slotallow_same_items、slot_limit、filter.enable
fluid_tankallow_same_fluids、capacity、filter.enable
forge_energy_storagecapacity、max_receive、max_extract
entity_handlerarea
chemical_tankallow_same_chemicals、capacity、filter.enable
ars_source_storagecapacity、max_receive、max_extract、expose_to_devices
ars_nearby_sourceradius、scan_interval、particles
aura_handlerradius
ae2_me_interface、ae2_me_pattern_provideritem_capacity、fluid_capacity
pneumatic_pressure_air_handlervolume、max_pressure、danger_pressure、critical_pressure、connection_io.{...}

任何机器的权威清单是 machine.runtimeValues.slots(),或者 Runtime Value Names 蓝图节点。

在蓝图里 ​

mbd2/machine 和 mbd2/machine/action 分组提供了完整接口,见节点参考。包括类型化读取(Get Runtime Int、Get Runtime IO 等)、类型化写入(Set Runtime Value (Number) 等)、Is Runtime Value Overridden、Clear Runtime Value、Clear All Runtime Values,以及 auto IO 和 capability IO 的快捷节点。

在 KubeJS 里 ​

机器和任意 Trait 上都有按名字访问的入口:

js
MBDMachineEvents.onPlaced('example:crusher', wrapper => {
  const machine = wrapper.event.machine

  machine.runtimeValues.set('machine_level', 3)
  console.info(`${machine.getMachineLevel()} (authored ${machine.runtimeValues.authored('machine_level')})`)

  const slots = machine.getTraitByName('item_slot')
  slots.runtimeValues.set('auto_io.enable', true)
  slots.runtimeValues.set('auto_io.front', 'OUT')      // enum by name
  slots.runtimeValues.set('auto_io.interval', 10)
})

常用项有便捷方法:

js
machine.setMachineLevel(5)
machine.clearMachineLevel()

const slots = machine.getTraitByName('item_slot')
slots.setAutoIOEnabled(true)
slots.setAutoIOSide('up', IO.OUT)     // 世界方向,会按机器朝向解析
slots.setAutoIOInterval(7)
slots.setCapabilityIOSide('north', IO.NONE)
slots.clearAutoIO()

已经拿到槽位对象时也可以直接走字段链:

js
slots.autoIO.enable.setValue(false)
slots.autoIO.front.setValue(IO.OUT)
console.info(`${slots.autoIO.interval.get()} ${slots.autoIO.enable.isOverridden()}`)

槽位对象上用 setValue,不要用 set

RuntimeValue.set(T) 擦除成 set(Object),Rhino 不会把 JS 原始值绑定到它——slot.set(false) 会抛 Can't find method ...set(boolean)。setValue(Object) 会做转换,是给脚本用的入口。runtimeValues.set(key, value) 不是泛型方法,可以正常绑定。

类型转换与报错 ​

写入槽位类型结果
7 或 7.0int7
7.9int抛异常——不会静默截断
'OUT'IOIO.OUT,忽略大小写
'true' / 'false'bool按写入;其他字符串抛异常
'input,catalyst'字符串列表["input", "catalyst"],去空格、丢空项
null任意抛异常——请用 clear()

未知的键会抛异常,并在消息里列出可用键,所以拼错会立刻发现而不是悄悄失效。

它属于哪一层 ​

需求用
这一类机器都这样编辑器里的定义
这一台机器不一样runtime value
玩家在游戏里配置runtime value,从蓝图 UI 写入
客户端要能看到这个值自定义数据,不是 runtime value
客户端要能持久保存两者都不行——它是服务端状态

Released under the MIT License.