From a84bf3c2aa374092bb7776de8255b8f2c5429ae4 Mon Sep 17 00:00:00 2001 From: jurrejelle Date: Tue, 27 Jan 2026 11:50:32 +0100 Subject: [PATCH 1/3] Start of MUI2 sync docs --- .../MUI2/Syncing/Basic-Sync-Example.md | 29 +++++++++++++++ .../Development/MUI2/Syncing/SyncManager.md | 6 ++++ .../content/Development/MUI2/Syncing/index.md | 1 + docs/content/Development/MUI2/Test-Machine.md | 35 +++++++++++++++++++ docs/content/Development/MUI2/index.md | 5 +++ 5 files changed, 76 insertions(+) create mode 100644 docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md create mode 100644 docs/content/Development/MUI2/Syncing/SyncManager.md create mode 100644 docs/content/Development/MUI2/Syncing/index.md create mode 100644 docs/content/Development/MUI2/Test-Machine.md create mode 100644 docs/content/Development/MUI2/index.md diff --git a/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md b/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md new file mode 100644 index 00000000000..409e6c09598 --- /dev/null +++ b/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md @@ -0,0 +1,29 @@ +# Basic Sync Example + +```java +public class MuiTestMachine extends MetaMachine implements IMuiMachine { + + public int ticks = 0; + public MuiTestMachine(BlockEntityCreationInfo info) { + super(info); + this.subscribeServerTick(() -> ticks++); + } + + @Override + public ModularPanel buildUI(PosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var panel = GTGuis.createPanel(this, 176, 168); + var tickSyncValue = new IntSyncValue(() -> this.ticks, (newValue) -> this.ticks = newValue); + syncManager.syncValue("tickSyncValue", tickSyncValue); + + panel.child(IKey.dynamic(() -> Component.literal("Ticks: "+ this.ticks)) + .asWidget() + .margin(4)); + + return panel; + } +} +``` + +Here, we create a basic SyncValue for an integer. This takes a `Supplier` and a `Consumer`, more commonly known as a getter and a setter. If the value is changed, either on the server or the client, the value gets serialized and sent to the other side, so the client knows about the value. + +If you try to access values that aren't synced or don't have a SyncValue or SyncHandler, they will be `0` or `null`. \ No newline at end of file diff --git a/docs/content/Development/MUI2/Syncing/SyncManager.md b/docs/content/Development/MUI2/Syncing/SyncManager.md new file mode 100644 index 00000000000..dc12a0618bd --- /dev/null +++ b/docs/content/Development/MUI2/Syncing/SyncManager.md @@ -0,0 +1,6 @@ +# SyncManager +A `PanelSyncManager` is the panel-level coordinator that keeps server state and client UI in sync. + +You register `SyncValue`s and other `SyncHandler`s on it during `buildUI`. Then, these are checked every server tick, and any changes are shipped to the other side. + +This is what makes widgets reflect live data and makes client-side interactions safely update the server. diff --git a/docs/content/Development/MUI2/Syncing/index.md b/docs/content/Development/MUI2/Syncing/index.md new file mode 100644 index 00000000000..ed0a1fb6e5f --- /dev/null +++ b/docs/content/Development/MUI2/Syncing/index.md @@ -0,0 +1 @@ +Syncing is the concept of synchronising data between client and server. This folder will contain files relevant to setting up syncing on your UIs. \ No newline at end of file diff --git a/docs/content/Development/MUI2/Test-Machine.md b/docs/content/Development/MUI2/Test-Machine.md new file mode 100644 index 00000000000..63d3a9135c5 --- /dev/null +++ b/docs/content/Development/MUI2/Test-Machine.md @@ -0,0 +1,35 @@ +# Making a MUI2 Test Machine +To make a basic machine to test your UI, simply create the following class: + +```java title="MultiMachines.java" +public class MuiTestMachine extends MetaMachine implements IMuiMachine { + + public MuiTestMachine(BlockEntityCreationInfo info) { + super(info); + } + + @Override + public ModularPanel buildUI(PosGuiData data, PanelSyncManager syncManager, UISettings settings) { + var panel = GTGuis.createPanel(this, 176, 168); + // Do stuff with your panel here, add children, etc. + // For example: + panel.child(IKey.str("Test machine") + .asWidget() + .margin(4)); + + return panel; + } +} +``` + +and in your machines definitions class, add the following entry: + +```java + public static final MachineDefinition MUI_TEST_MACHINE = REGISTRATE + .machine("mui_test", MuiTestMachine::new) + .model(createOverlayCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_clean_stainless_steel"), + GTCEu.id("block/machine/part/computer_monitor"))) + .register(); +``` + +Make sure to run datagen after making the initial machine to register the lang keys, model, etc. Running datagen afterward for UI changes is not required. \ No newline at end of file diff --git a/docs/content/Development/MUI2/index.md b/docs/content/Development/MUI2/index.md new file mode 100644 index 00000000000..f06372b41a0 --- /dev/null +++ b/docs/content/Development/MUI2/index.md @@ -0,0 +1,5 @@ +# ModularUI 2 +ModularUI 2 is the UI library used in GTM starting from 8.0.0, and is the successor to LDLib UI. +From ModularUI 1.12's github: + +With ModularUI you can build GUIs fast by adding Widgets to panels with layout widgets, so you don't have to calculate positions and sizes yourself. ModularUI is very dynamic and allows for very complicated client-server synced GUIs. \ No newline at end of file From f0ad27955935a782dea03588fdfab54039a117a4 Mon Sep 17 00:00:00 2001 From: jurrejelle Date: Tue, 27 Jan 2026 11:52:47 +0100 Subject: [PATCH 2/3] the client -> other side --- docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md b/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md index 409e6c09598..c0409ab419b 100644 --- a/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md +++ b/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md @@ -24,6 +24,6 @@ public class MuiTestMachine extends MetaMachine implements IMuiMachine { } ``` -Here, we create a basic SyncValue for an integer. This takes a `Supplier` and a `Consumer`, more commonly known as a getter and a setter. If the value is changed, either on the server or the client, the value gets serialized and sent to the other side, so the client knows about the value. +Here, we create a basic SyncValue for an integer. This takes a `Supplier` and a `Consumer`, more commonly known as a getter and a setter. If the value is changed, either on the server or the client, the value gets serialized and sent to the other side, so the other side knows about the value. If you try to access values that aren't synced or don't have a SyncValue or SyncHandler, they will be `0` or `null`. \ No newline at end of file From 7b63e115034a3a0fabd8bf3166ebf4cd61284af2 Mon Sep 17 00:00:00 2001 From: jurrejelle Date: Tue, 27 Jan 2026 12:26:54 +0100 Subject: [PATCH 3/3] Update sync example based on brachy's comments --- docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md b/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md index c0409ab419b..0e56d629878 100644 --- a/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md +++ b/docs/content/Development/MUI2/Syncing/Basic-Sync-Example.md @@ -24,6 +24,8 @@ public class MuiTestMachine extends MetaMachine implements IMuiMachine { } ``` -Here, we create a basic SyncValue for an integer. This takes a `Supplier` and a `Consumer`, more commonly known as a getter and a setter. If the value is changed, either on the server or the client, the value gets serialized and sent to the other side, so the other side knows about the value. +Here, we create a basic `SyncValue` for an integer. This takes a `Supplier` and a `Consumer`, more commonly known as a getter and a setter. Generally speaking, `SyncValue`s will take a `Supplier` and `Consumer` of the type of value they are syncing. -If you try to access values that aren't synced or don't have a SyncValue or SyncHandler, they will be `0` or `null`. \ No newline at end of file +If the value returned by the getter changed on the server, the value gets serialized and sent to the client by the `SyncManager`. The `SyncHandler`'s value can always be manually updated, for example to do client-to-server syncing. + +If you try to access values on the client that aren't synced or don't have a `SyncValue` or `SyncHandler`, they will have a default value, but they will not reflect the values or changes happening on the server. \ No newline at end of file