Skip to content

Updating from 7.4.1 to 7.5.0

Note

Because of these changes, when using GTM 7.5.0+ you can not compile your mod(pack) against addons or coremods that are compiled for 7.4.1 and touch anything related to machines. Make sure that your dependencies have updated.

Machine Builder Generics

We have added a second Generic argument to our (Multiblock)MachineBuilder. This effectively means that anywhere where you used to store a partially finished MachineBuilder<?>, you now need to store a MachineBuilder<?, ?>. The same holds for MultiblockMachineBuilder<?, ?>.

Machine & Cover Copy/Paste System

A new system for copying machines using the Machine Memory Card has been added, see this page if you want to add extra copy/paste behaviour to your own machines and covers.

Multiblock Structure Change

The Large Fractionating Still no longer requires a muffler hatch, allowing it to be used in cleanrooms.

RecipeCondition Generics

We have added a Generic argument to RecipeCondition describing the condition.
This means that your custom recipe conditions now need to extend RecipeCondition<MyCondition> (whereas before they just extended RecipeCondition). For example, if you have a custom recipe condition class like so: public class ExampleCondition extends RecipeCondition, it should now be public class ExampleCondition extends RecipeCondition<ExampleCondition>.
You also need to adjust the generics of getType() and createTemplate() to match this change, like so:

- public RecipeConditionType<?> getType() {
+ public RecipeConditionType<ExampleCondition> getType() {

- public RecipeCondition createTemplate() {
+ public ExampleCondition createTemplate() {

Mortar Recipe Fix

Previously, adding GTToolType.MORTAR to your tool did not automatically generate the recipe. This has been fixed. If you previously generated a recipe using this, you need to remove your manual recipe.

Pipe rendering changes

This is only relevant to add-on mods with custom pipe types. Addons with custom pipe implementations will have to tweak their code slightly to function with the new rendering code (see example below).

-public final PipeModel model = new PipeModel(pipeType.getThickness(), () -> [side texture], () -> [end texture], null, null); 
-@Getter
-private final PipeBlockRenderer renderer = new PipeBlockRenderer(model);

 ...

 @Override
-public PipeModel getPipeModel() {
-    return model;
+public PipeModel createPipeModel(GTBlockstateProvider provider) {
+    return new PipeModel(this, pipeType.getThickness(), [side texture], [end texture], provider);
 }
If your pipe is generated from a material property (or equivalent), you should also call PipeModel#dynamicModel() to have models be generated at runtime.
If so, must also add a Mod bus event listener for RegisterDynamicResourcesEvent, like so:
@SubscribeEvent
public static void registerDynamicResources(RegisterDynamicResourcesEvent event) {
   for (var block : MyBlocks.MY_PIPE_BLOCKS) block.get().createPipeModel(RuntimeExistingFileHelper.INSTANCE).dynamicModel();
}
Replace MyBlocks.MY_PIPE_BLOCKS with a reference to your pipe block array/map value collection.

Conversely, if the pipe is not generated, but has a constant set of variants (such as optical fiber cables or laser pipes), you should NOT use PipeModel#dynamicModel() and instead set the model with GTBlockBuilder#gtBlockstate as such:

    // on your pipe block builder
    ... = REGISTRATE.block(...)
             .properties(...)
             .gtBlockstate(GTModels::createPipeBlockModel)
             ...more builder things...
             .item(...)
             .model(NonNullBiConsumer.noop())
             ...more builder things...

Lamp Predicates

Previously, lamps were not useable with the terminal in multiblocks. There are new lamp predicates that will help solve this problem. The predicate to use all lamps is: Predicates.anyLamp() The predicate to use a specific color is: Predicates.lampsByColor(DyeColor.DYE_COLOR). Where DYE_COLOR is the name of the color you want.

GTRecipeBuilder#adjacentFluidTag() and GTRecipeBuilder#adjacentBlockTag()

This is only relevant to add-on mods with custom recipe types that use the condition(s). KubeJS recipes are not affected.

The renames of GTRecipeBuilder#adjacentFluid(TagKey<Fluid>...) -> #adjacentFluidTag(TagKey<Fluid>...) and GTRecipeBuilder#adjacentBlock(TagKey<Block>...) -> #adjacentBlockTag(TagKey<Block>...) have been deprecated in favor of naming every variant adjacentFluids and adjacentBlocks, respectively.
Please update your addon mods' recipes to use these new methods, as the now deprecated methods will be removed come 8.0.0.

A full list of all deprecated methods & their replacement is as follows:
Fluids: adjacentFluid, adjacentFluidTag -> adjacentFluids
Blocks: adjacentBlock, adjacentBlockTag -> adjacentBlocks

Machine Recipe Failure Diagnostics

Machines now provide detailed diagnostics explaining why recipes fail to start.

Failure reasons are displayed in: - the sidebar of simple machines - the UI of multiblock machines - the Jade tooltip for all machines

You are supposed to replace ModifierFunction.NULL with ModifierFunction.cancel(reason) to tell the machine why the recipe fails to start.

- return ModifierFunction.NULL;
+ return ModifierFunction.cancel(Component.translatable("gtceu.recipe_modifier.xxx"));

Also, if you cancel a recipe in IRecipeLogicMachine#beforeWorking(), you are supposed to add some custom reason info like:

@Override
public boolean beforeWorking(@Nullable GTRecipe recipe) {
    if(xxx){
        RecipeLogic.putFailureReason(this, recipe, Component.literal("Machine spirit is displeased"));
        return false
    }
    return true;
}

Painted Output Buses/Hatches

For some time, Spray Paint cans could be used to paint Input and Output Buses/Hatches on multiblock machines. Version 7.0.0 added the feature that Painted Input Buses/Hatches of different colors would not share their ingredients with each other when the machine ran recipes. This system is more fully explained at Painted Inputs and Outputs.

7.5.0 also applies this logic to Output Buses/Hatches as well. Input Buses/Hatches which have been painted are now only allowed to send their outputs to Output Buses/Hatches that are of the same paint color, or unpainted. This may cause existing setups to stop running, if they had painted Output Buses/hatches on them.

Change to GTRecipe constructor

GTRecipe has had one new field added to it and its constructors: int groupColor. For new recipes, this parameter is set to -1; however for recipes that are being prepared and run, this field holds the Paint color of the Painted Input Group that the recipe drew its inputs from.

Addon mods which explicitly attempt to construct, copy, or apply their own ModifierFunctions to a GTRecipe (not using the standard builder or kjs functions) will need to either add the additional int parameter to the end of their constructor calls, or the additional recipe.groupColor to their copy calls.

Added BiomeTagCondition

Added a new RecipeCondition called BiomeTagCondition for needing a specific biome tag. This can be used with KubeJS using .biomeTag("biome").