UI
You might have used mbd2’s visual editor to create the UI, but you may have noticed that apart from the trait widget, the other widgets don't really work. This is because we haven't set up the UI logic, such as what should happen when a button is pressed. As mentioned in the Ldlbib UI, we recommend using the UI Editor to create and edit the UI layout, and using KubeJS
/ to set up the interaction logic.NodeGraph (W.I.P)
Here, we implement a simple, UI-based manual lava filling machine.
First, we configure the machine to have one item trait and one fluid trait, and prepare our UI:
- A UI corresponding to the trait.
- Two
buttons
corresponding to the filling directions. - A
TextTexture
to display the amount of fluid in the tank.
Once you have everything set up, opening the machine's UI should look like this:
KubeJS Control
Next, we use KubeJS to add interaction logic to the UI.
We provide an event MBDMachineEvents.onUI
for you to setup the root widget. This event is triggered after MBDMachineEvents.onOpenUI
and everything is prepared except the logic.
MBDMachineEvents.onUI("mbd2:kjs_ui_test", e => {
const { machine, root } = e.event;
const slot = root.getFirstWidgetById("ui:item_slot_0") // SlotWidget
const tank = root.getFirstWidgetById("ui:fluid_tank_0") // FluidTankWidget
const fill_button = root.getFirstWidgetById("fill_button") // Button
const drain_button = root.getFirstWidgetById("drain_button") // Button
const label = root.getFirstWidgetById("tank_label") // TextWidget
// Set label to display fluid amount
label.setTextProvider(() => Component.string(tank.fluid.amount + "mB"))
// on button click
fill_button.setOnPressCallback(clickData => {
if (clickData.isRemote) {
// trigger on the remote side
// because everything is synced from server to client. you can do nothing on the remote side
} else {
var stored = slot.item
// check if a lava bucket is stored
if (stored && stored.id === "minecraft:lava_bucket") {
// check if there is enough space in the tank
if (tank.lastTankCapacity - tank.fluid.amount >= 1000) {
// remove the lava bucket
slot.item = { item: "minecraft:bucket", count: 1 }
// add 1000mB of lava to the tank
tank.fluid = { fluid: "minecraft:lava", amount: tank.fluid.amount + 1000 }
}
}
}
})
drain_button.setOnPressCallback(clickData => {
if (!clickData.isRemote) {
// check if there is lava in the tank
if (tank.fluid.amount >= 1000 && slot.item.id === "minecraft:bucket") {
// remove 1000mB of lava from the tank
tank.fluid = { fluid: "minecraft:lava", amount: tank.fluid.amount - 1000 }
// add a lava bucket
slot.item = { item: "minecraft:lava_bucket", count: 1 }
}
}
})
})
Let's see our final result!
We only use four widgets here (TextTexture
, Button
, Slot
, and Tank
). For more details about other widgets please check pages.
Display part's trait ui in the Controller / Display controller's trait ui in the Part
MBD2 supports proxy capabilities, allowing you to use a part to proxy the capabilities of a controller. However, you might also want to display the UI of a trait defined in the controller within the part, or vice versa—display a trait from a part in the controller’s UI. This is possible, but it requires some additional setup.
For example, suppose your part has an item trait named item_slot
with only one slot. Its UI ID would be ui:item_slot_0
. To display it in the controller’s UI, you need to manually add an item slot widget to the controller UI and set its ID to part:item_slot@ui:item_slot_0
.
Similarly, let’s say your controller has a PneumaticCraft air trait named air_handler
. To display it in the part's UI, you need to manually add a progress bar widget (you can also temporarily add a trait to auto-generate the UI, then remove the trait), and set the widget's ID to controller:air_handler@ui:air_handler
.