Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e8eb858
Document modifying and removing veins (#4956)
jurrejelle Jun 25, 2026
d5448f5
Sync Handler Docs (#4997)
jurrejelle Jun 25, 2026
fc71f1a
Add property modification to material modification docs (#4951)
jurrejelle Jun 25, 2026
b91d3e3
Fix recipe widget now showing all emi recipe categories (#4994)
YoungOnionMC Jun 26, 2026
5b7eaaa
Replace MainAxisAlignment image (#5004)
jurrejelle Jun 26, 2026
9fd3d1f
Fixed up some typos/broken/missing formatting with onion's docs. (#5010)
Phoenixvine32908 Jun 28, 2026
1e3d584
remove redundant preinit stencil call (#5018)
jurrejelle Jun 29, 2026
5e93de8
Steam dial widget for Steam Machines (#5006)
YoungOnionMC Jun 30, 2026
ac93f1e
Add pickaxe tag to lamps (#4981)
YoungOnionMC Jun 30, 2026
09f0ace
Fix ordering of crystal mainframe circuit (#4979)
YoungOnionMC Jun 30, 2026
ea30a5f
Onion UI cleanup PT 2 (#5026)
YoungOnionMC Jun 30, 2026
6a7b7c6
Fix auto output trait on load (#5025)
YoungOnionMC Jun 30, 2026
28263fa
Onion Machine UI cleanup p3 (#5028)
YoungOnionMC Jun 30, 2026
2ffc0aa
Remove Chance Boosting (#4968)
DilithiumThoride Jun 30, 2026
1843bb8
Large Bronze Boiler UI (#5033)
YoungOnionMC Jun 30, 2026
cf0ed10
fix fluid tooltip duplication (#5036)
gustovafing Jun 30, 2026
8b93f38
More Arc Furnace Slots (#4993)
YoungOnionMC Jul 2, 2026
cb1ef51
Primitive Pump UI (#5039)
YoungOnionMC Jul 4, 2026
4531434
Schema parts catalyst (#5050)
YoungOnionMC Jul 5, 2026
a390555
G^2
Ghostipedia Jul 5, 2026
374a635
Bump MUI (#5063)
jurrejelle Jul 6, 2026
342f928
Final parts of machine refactor (#4925)
gustovafing Jul 6, 2026
5a64605
Fix broken Antidote behaviors (#4798)
Vykonn Jul 7, 2026
e07ee9d
Add version sync log workflow (#5042)
jurrejelle Jul 8, 2026
f4c79f0
Fix screwdriver drum (#5067)
YoungOnionMC Jul 8, 2026
be9b437
Add TARGET_REPO to version sync workflow (#5070)
jurrejelle Jul 8, 2026
fa49b23
exclude steam dial in xei (#5072)
jurrejelle Jul 10, 2026
3f6b66c
fix drum/crate drops (#5073)
jurrejelle Jul 11, 2026
0e6ceaf
bump emi to match mui (#5074)
jurrejelle Jul 11, 2026
c2f4459
Fix nullable machines crashing EMI plugin (#5075)
jurrejelle Jul 11, 2026
e436a7a
Fix prospection data task (#5076)
jurrejelle Jul 11, 2026
03346e4
Fix notifiable circuit slot not notifying RL (#5081)
jurrejelle Jul 11, 2026
0e64614
Fix charcoal pire ingiter structure (#5080)
jurrejelle Jul 11, 2026
fc787a3
Fix Machine slot sync handlers for fluids (#5082)
YoungOnionMC Jul 11, 2026
4edf34d
Fix machine type limits not being applied (#5083)
htmlcsjs Jul 12, 2026
dbf410b
Fix Steam Energy Handler Transformer (#5085)
YoungOnionMC Jul 12, 2026
f3bd706
Slot capability accessibility (#5086)
YoungOnionMC Jul 12, 2026
7a55019
Fix Xaero's OreVein icons (#5087)
YoungOnionMC Jul 12, 2026
fc508bb
Merge 1.20.1 into gus/update-1.21
gustovafing Jul 12, 2026
a203663
Merge 1.20.1 into gus/update-1.21
gustovafing Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ Client sync fields **do not** automatically detect changes. When changing a clie
- `@RequireRerender` -> `@RerenderOnChanged`
- `@Persisted` -> `@SaveField`
- `@UpdateListener` -> `@ClientFieldChangeListener` on listener method.
- `@DropSaved` - Removed, make machines implement `IDropSaveMachine` instead
- `@DropSaved` - Replaced with overriding the `loadFromItem`/`saveToItem` methods on `MetaMachine`
- `@ReadOnlyManaged` and `@LazyManaged` See usage docs for instructions on complex sync objects


### Other changes

- `saveCustomPersistedData` & `loadCustomPersistedData` methods, and serialization of custom data types - See `ValueTransformer<T>` and `ValueTransformers` classes.
Binary file modified docs/content/Development/MUI2/Layout_MainAxisAlignments.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions docs/content/Development/MUI2/Syncing/Sync-Basics.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Sync Basics
---
title: Sync Basics
---

## Basics of Syncing
To display dynamic values on the client, you have to send the data from the server to the client. When making UIs, it is very important to keep track of if and how your data is being synced to the client. There are a few ways to do so, which will be discussed below.
Expand All @@ -20,7 +22,8 @@ This would not work, intSyncValue hasn't had time to send data over yet and thus

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.


!!! Note
By default, `SyncValue`s or `SyncHandler`s don't allow client-to-server syncing. For that you will need to chain `.allowC2S()`. This gets called on the `SyncHandler` itself, so if you're using a builder, after the `.build()`

## Method 1: Dynamic Widgets
The first method is using dynamic widgets, which update every frame regardless of what happens.
Expand Down
94 changes: 94 additions & 0 deletions docs/content/Development/MUI2/Syncing/Sync-Handlers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: Sync Handlers
---


## What are they
A `SyncHandler` is a mechanism that handles the syncing between client and server for MUI2. For its high level usages, see [Sync Basics](Sync-Basics.md). `SyncHandler`s generally can sync anything between client and server, and `SyncValue`s specifically sync data (e.g. a value) between client and server.

## How they work
You can create a `SyncHandler` with the following syntax:
`new IntSyncValue(() -> this.number, (newValue) -> this.number = newValue)`
This means that to check if the value changed, it will call the first argument (the IntSupplier, `() -> this.number`), and cache the value that gets returned.
Then, whenever that value changes, it will send the changed value to the other side.
Whenever a `SyncHandler` receives a value from the other side, it will call the setter with the value, in this case setting `this.number` to the new value on the client, and cache it for further use/checking.
Do note that this means that a setter isn't necessary. You can use only a getter, and then call `syncHandler.getValue()` to get the last received / cached value.

!!! Note
By default, `SyncValue`s or `SyncHandler`s don't allow client-to-server syncing. For that you will need to chain `.allowC2S()`. This gets called on the `SyncHandler` itself, so if you're using a builder, after the `.build()`



Here's a list of the built-in `SyncHandler`s:


- `BigDecimalSyncValue`
- `BigIntegerSyncValue`
- `BinaryEnumSyncValue`
- `BooleanSyncValue`
- `ByteArraySyncValue`
- `ByteSyncValue`
- `DoubleSyncValue`
- `EnumSyncValue`
- `FloatSyncValue`
- `FluidSlotSyncHandler`
- `GenericCollectionSyncHandler<T>`
- `GenericListSyncHandler<T>`
- `GenericMapSyncHandler<T>`
- `GenericSetSyncHandler<T>`
- `GenericSyncValue<T>`
- `IntSyncValue`
- `LongArraySyncValue`
- `LongSyncValue`
- `ShortSyncValue`
- `StringSyncValue`

## Generic Sync Handlers

In the previous list, I specifically want to draw attention to the Generic- SyncHandlers. These can take in custom methods for writing- and reading data for syncing stuff that isn't in this list.
e.g.
```java
GenericListSyncHandler<Integer> numberListSyncHandler = GenericListSyncHandler.<Integer>builder()
.getter(() -> this.serverInts)
.setter(v -> this.serverInts = v)
.serializer(FriendlyByteBuf::writeInt)
.deserializer(FriendlyByteBuf::readInt)
.immutableCopy()
.build();
```

To make this easier as to not have to re-invent the (de)serializers, you can use what's called an `IByteBufAdapter`. They hold serialize, deserialize and equals methods. So you could do
```java
GenericSyncValue<GTRecipe> recipeSyncHandler = GenericSyncValue.<GTRecipe>builder()
.getter(() -> rlmachine.getRecipeLogic().getLastRecipe())
.adapter(GTByteBufAdapters.GTRECIPE)
.build();
```
Here's a list of existing ByteBufAdapter:


- `ByteBufAdapters.ITEM_STACK`
- `ByteBufAdapters.FLUID_STACK`
- `ByteBufAdapters.NBT`
- `ByteBufAdapters.STRING`
- `ByteBufAdapters.BYTE_BUF`
- `ByteBufAdapters.FRIENDLY_BYTE_BUF`
- `ByteBufAdapters.INT`
- `ByteBufAdapters.LONG`
- `ByteBufAdapters.FLOAT`
- `ByteBufAdapters.DOUBLE`
- `ByteBufAdapters.BOOL`
- `ByteBufAdapters.BYTE`
- `ByteBufAdapters.SHORT`
- `ByteBufAdapters.CHAR`
- `ByteBufAdapters.BLOCKSTATE`
- `ByteBufAdapters.BLOCKPOS`
- `ByteBufAdapters.GLOBAL_POS`
- `ByteBufAdapters.RESOURCE_LOCATION`
- `ByteBufAdapters.UUID`
- `ByteBufAdapters.COMPONENT`
- `GTByteBufAdapters.MONITOR_GROUPS`
- `GTByteBufAdapters.PATTERN_ERRORS`
- `GTByteBufAdapters.GTRECIPE`

It is also possible to make your own ByteBufAdapter from a [CODEC](https://docs.minecraftforge.net/en/latest/datastorage/codecs/) using `ByteBufAdapters.makeAdapter(Codec<T> codec)`
4 changes: 3 additions & 1 deletion docs/content/Development/MUI2/Syncing/Synced-Actions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Synced Actions
---
title: Synced Actions
---

```java
public class MuiTestMachine extends MetaMachine implements IMuiMachine {
Expand Down
27 changes: 7 additions & 20 deletions docs/content/Modpacks/Changes/v8.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,8 @@ The constructors for a large number of machines have changed in order to simply

#### **All Machines**
- Replace the first constructor argument `IMachineBlockEntity holder` with `BlockEntityCreationInfo info`
#### `TieredEnergyMachine`
- Removed `createEnergyContainer` method
- Constructor now has an optional `NotifiableEnergyContainer` argument
#### `WorkableTieredMachine`
- Removed `createRecipeLogic`, `createImportItemHandler`, `createExportItemHandler`, `createImportFluidHandler`, `createExportFluidHandler` methods
- Added a new constructor:
- `BlockEntityCreationInfo info`
- `int tier`
- `RecipeLogic recipeLogic` Recipe logic, defaults to the standard `RecipeLogic` class.
- `int importSlots` Item import slots, defaults to the amount of slots in the machine's default recipe type.
- `int exportSlots` Same as above, but for item export slots.
- `int fluidImportSlots` As above, but for fluid import slots.
- `int fluidExportSlots` As above, but for fluid export slots.
- `boolean isEnergyEmitter` If this machine should emit/receiver energy.
- `Int2IntFunction tankScalingFunction` Fluid tank capacity scaling function.
#### `WorkableMultiblockMachine`, `WorkableElectricMultiblockMachine` and `SteamWorkableMachine`
- Removed `createRecipeLogic` method
- Constructor now has an optional `Supplier<RecipeLogic>` argument, defaults to the standard `RecipeLogic` class
#### Machines with `createX` functions (e.g. `createEnergyContainer`, `createRecipeLogic`)
- Creation functions have been removed in favor of arguments being passed into the constructor.

#### IMPORTANT MIGRATION NOTE:

Expand All @@ -110,6 +94,8 @@ When migrating, remove the `this` argument from the machine trait constructor an

A large number of machine feature interfaces have been removed, and have had their functionality merged into the standard MetaMachine class, or now use the new machine trait system:

- `IMultiPart` Use the `MultiblockPartMachine` class directly.
- `IWorkableMultiController` Use the `WorkableMultiblockMachine` class directly.
- `ITurbineMachine` Use the `LargeTurbineMachine` class directly.
- `IRotorHolderMachine` Use the `RotorHolderMachine` class directly.
- `IMultiController` Use the `MultiblockControllerMachine` class directly.
Expand All @@ -124,7 +110,7 @@ A large number of machine feature interfaces have been removed, and have had the
- `IHPCAComputationProvider` - Use `HPCAComputationProviderTrait`
- `IHPCACoolantProvider` - Use `HPCACoolantProviderTrait`
- `IFluidRendererMulti` - Use `MultiblockFluidRendererTrait`

- `IMaintenanceMachine` Use `MaintenanceHatchPartMachine`

## Connected texture reimplementation
The mod's connected texture logic has been reimplemented in GTM proper.
Expand Down Expand Up @@ -156,4 +142,5 @@ As a recipe-matching optimization, input handlers whose `getTotalContentAmount()
- Calling the battery buffer constructor with the following args gives the same behaviour as a charger machine: `(info, tier, inventorySize, BatteryBufferMachine.AMPS_PER_BATTERY_CHARGER, 0)`
- Refactored Jade provider code. Use the `MachineInfoProvider` class for jade providers for a specific machine type, and `MachineTraitProvider` for providers for a specific machine trait.
- `GTUtil.getMoltenFluid(Material)` has been moved to `Material.getHotFluid()`.
- `ICopyable::copyConfig`'s `CompoundTag` argument should now be mutated by reference instead of a new one returned (and thus, the return type has been changed to `void`).
- `ICopyable::copyConfig`'s `CompoundTag` argument should now be mutated by reference instead of a new one returned (and thus, the return type has been changed to `void`).
- Tiered Chance Boosting has been formally removed from the API (as it was deprecated in v7.0.) `ChancedInput` and `ChancedOutput` kubeJS calls will throw errors if they still had chance boost values as arguments.
2 changes: 1 addition & 1 deletion docs/content/Modpacks/Examples/Multiblocks/Greenhouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ title: "Greenhouse"
## Multiblock
=== "JavaScript"
```js title="greenhouse_multiblock.js"
const $RecipeLogic = Java.loadClass('com.gregtechceu.gtceu.api.machine.trait.RecipeLogic')
const $RecipeLogic = Java.loadClass('com.gregtechceu.gtceu.api.machine.trait.recipe.RecipeLogic')
const $List = Java.loadClass('java.util.List')

GTCEuStartupEvents.registry('gtceu:machine', event => {
Expand Down
72 changes: 52 additions & 20 deletions docs/content/Modpacks/Examples/Parallel-Hatch-Part.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,61 @@ title: "Custom Parallel Hatch"
## Parallel Hatch

```js title="extra_parallel_hatch.js"

const $ParallelHatchPartMachine = Java.loadClass(
'com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine'
) // (1)
"com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine"
); // (1)

GTCEuStartupEvents.registry("gtceu:machine", (event) => {
event
.create("parallel_hatch", "custom") // (2)
.tiers(GTValues.UHV, GTValues.UIV, GTValues.UEV, GTValues.UXV) // (3)
.machine((holder, tier, tankScaling) => {
return new $ParallelHatchPartMachine(holder, tier); // (4)
})
.definition((tier, builder) => {
let name = "Simple";
switch (tier) {
case GTValues.UHV:
name = "Epic";
break;
case GTValues.UIV:
name = "Legendary";
break;
case GTValues.UEV:
name = "Spectral";
break;
case GTValues.UXV:
name = "Universal";
break;
}

GTCEuStartupEvents.registry('gtceu:machine', event => { // (2)
event.create(
"uhv_parallel_hatch", // (3)
"custom",
(holder, tier) => {
return new $ParallelHatchPartMachine(holder, tier);
},
GTValues.UHV // (4)
)
.abilities(PartAbility.PARALLEL_HATCH) // (5)
.workableTieredHullRenderer(GTCEu.id("block/machines/parallel_hatch_mk4")) // (6)
})
const $RecipeLogic = Java.loadClass(
"com.gregtechceu.gtceu.api.machine.trait.recipe.RecipeLogic"
);
builder
.langValue(name + " Parallel Control Hatch")
.rotationState(RotationState.ALL)
.abilities(PartAbility.PARALLEL_HATCH) // (5)
.modelProperty($RecipeLogic.STATUS_PROPERTY, $RecipeLogic.Status.IDLE)
.model(
GTMachineModels.createWorkableTieredHullMachineModel(
GTCEu.id("block/machines/parallel_hatch_mk4") // (6)
)[
"andThen(com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder$ModelInitializer)"
]((ctx, prov, model) => {
model.addReplaceableTextures("bottom", "top", "side");
})
)
}); // (7)
});
```

1. Loading the java class that is required to build the parallel hatch multi part
2. Using the GT registry event to register the multi part, which is part of machine registry
3. The ID for the new parallel hatch
4. The tier used for the parallel hatch
1. Loading the parallel hatch's java class is required
2. Using the GT registry event to register a tiered custom machine
3. The tiers to register the machine for
Here, GT will generate items and blocks named `gtceu:uhv_parallel_hatch`, `gtceu:uev_parallel_hatch`, `gtceu:uiv_parallel_hatch`, and `gtceu:uxv_parallel_hatch`
4. Use the loaded class for creating the machines in the world
5. Specifying the multipart to use parallel hatch ability
6. The texture to use for the multipart, this example just uses the t4 texture as a placeholder
You can look at gtm's assets to see the animations and textures to edit
You can look at gtm's assets to see the animations and textures to edit
7. You can just refer to the code in GCYMMachines.PARALLEL_HATCH here
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ title: Modifying Existing Materials
All periodic table elements are present in GT, but some of them don't have any properties attached. You can also add a BlastProperty for EBF autogenerated recipes. You can also do this for other materials such as Obsidian. Here is how you can add them:

```js title="periodic_table_elements.js"
const $IngotProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.IngotProperty');
const $DustProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.DustProperty');
const $BlastProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.BlastProperty');
const $IngotProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.IngotProperty');
const $DustProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.DustProperty');
const $BlastProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.BlastProperty');

GTCEuStartupEvents.registry('gtceu:material', event => {
GTCEuStartupEvents.registry('gtceu:material', event => {

// Ingot
GTMaterials.Zirconium.setProperty(PropertyKey.INGOT, new $IngotProperty());
GTMaterials.Obsidian.setProperty(PropertyKey.INGOT, new $IngotProperty());
// Ingot
GTMaterials.Zirconium.setProperty(PropertyKey.INGOT, new $IngotProperty());
GTMaterials.Obsidian.setProperty(PropertyKey.INGOT, new $IngotProperty());

// Dust
GTMaterials.Selenium.setProperty(PropertyKey.DUST, new $DustProperty());
// Dust
GTMaterials.Selenium.setProperty(PropertyKey.DUST, new $DustProperty());

// Blast Property
GTMaterials.Zirconium.setProperty(PropertyKey.BLAST, new $BlastProperty(8000, 'higher', GTValues.VA[GTValues.MV], 8000));
// Blast Property
GTMaterials.Zirconium.setProperty(PropertyKey.BLAST, new $BlastProperty(8000, 'higher', GTValues.VA[GTValues.MV], 8000));

});
});
```

Adding fluids to existing materials requires a bit of work with the new FluidStorage system
Expand All @@ -35,50 +35,57 @@ const $FluidProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.m
const $FluidBuilder = Java.loadClass('com.gregtechceu.gtceu.api.fluids.FluidBuilder');
const $FluidStorageKeys = Java.loadClass('com.gregtechceu.gtceu.api.fluids.store.FluidStorageKeys');

GTCEuStartupEvents.registry('gtceu:material', event => {
addFluid(GTMaterials.Iodine, $FluidStorageKeys.LIQUID); // Can be LIQUID, GAS, PLASMA or MOLTEN
addFluid(GTMaterials.Oganesson, $FluidStorageKeys.GAS);
}


let addFluid = (mat, key) => {
let prop = new $FluidProperty();
prop.getStorage().enqueueRegistration(key, new $FluidBuilder());
mat.setProperty(PropertyKey.FLUID, prop);
}

GTCEuStartupEvents.registry('gtceu:material', event => {
addFluid(GTMaterials.Iodine, $FluidStorageKeys.LIQUID); // Can be LIQUID, GAS, PLASMA or MOLTEN
addFluid(GTMaterials.Oganesson, $FluidStorageKeys.GAS);
});
```

You can even add an ore to existing materials:

```js title="ore_property.js"
GTCEuStartupEvents.registry('gtceu:material', event => {
GTCEuStartupEvents.registry('gtceu:material', event => {

const $OreProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.OreProperty');
const $OreProperty = Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.OreProperty');

// Zinc Ore
GTMaterials.Zinc.setProperty(PropertyKey.ORE, new $OreProperty());

});
GTMaterials.Zinc.setProperty(PropertyKey.ORE, new $OreProperty());

});
```

Do note that to edit keys that already exist on materials, you have to remove them first:
```js title="modifying_properties.js"
const $WireProperties = Java.loadClass("com.gregtechceu.gtceu.api.data.chemical.material.properties.WireProperties")

GTCEuStartupEvents.registry('gtceu:material', event => {
GTMaterials.RedAlloy.removeProperty(PropertyKey.WIRE)
GTMaterials.RedAlloy.setProperty(PropertyKey.WIRE, new $WireProperties(8, 1, 0, true))
})
```
You can also add flags to existing materials:

```js title="flags.js"
GTCEuStartupEvents.registry('gtceu:material', event => {
GTCEuStartupEvents.registry('gtceu:material', event => {

GTMaterials.Lead.addFlags(GTMaterialFlags.GENERATE_GEAR); // This is for materials already in GTCEU
GTMaterials.get('custom_material_name').addFlags(GTMaterialFlags.GENERATE_FOIL); // This only works for materials added by GTCEU addons
});
GTMaterials.Lead.addFlags(GTMaterialFlags.GENERATE_GEAR); // This is for materials already in GTCEU
GTMaterials.get('custom_material_name').addFlags(GTMaterialFlags.GENERATE_FOIL); // This only works for materials added by GTCEU addons

});
```

Editing the color of an existing material:


```js title="material_modification.js"
GTCEuStartupEvents.materialModification(event => {
GTMaterials.BismuthBronze.setMaterialARGB(0x82AD92) //(1)
})
GTCEuStartupEvents.materialModification(event => {
GTMaterials.BismuthBronze.setMaterialARGB(0x82AD92) //(1)
})
```

1. Most methods in the [``Material`` class](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/api/data/chemical/material/Material.java) can be used in the ``materialModification`` event
Loading
Loading