Skip to main content
The Upgrades API lets you create upgrade items that modify machine behavior and attach compatible upgrade lists to specific block entities.

UpgradeBase

UpgradeBase is the base class for all upgrade items. It extends BaseItem.
public class UpgradeBase extends BaseItem

Constructor

public UpgradeBase(Item.Properties properties, String description)
properties
Item.Properties
required
Standard NeoForge item properties.
description
String
required
English description shown in the item tooltip when the player holds Shift.

Methods

// Attempt to apply this upgrade to a block; throws if the block is not Upgradeable
void functionalUpgrade(BaseEntityBlock<?> block, BlockState state)

// Mark the upgrade as applied or unapplied
boolean setApplied(boolean hasBeenApplied)

// Check whether this upgrade instance has been applied
boolean hasBeenApplied()

// Return the English description string
String getEnglishDescription()
The tooltip behavior is built in: pressing Shift shows the description component; without Shift it shows the gui.gm.press_shift localization key.

Upgradeable interface

Upgradeable marks a block entity as capable of holding upgrades.
public interface Upgradeable {
    ItemStackHandler getUpgradeInventory();
}
Return an ItemStackHandler that represents the upgrade slots of your machine. The handler’s slot count determines how many upgrades can be installed simultaneously.

UpgradeMap

UpgradeMap is a record that associates a block entity type with an ordered list of compatible upgrade/max-stack pairs.
public record UpgradeMap<T extends BlockEntity>(
    DeferredBlockEntityType<T> entity,
    ImmutableList<Pair<ItemDefinition<UpgradeBase>, Integer>> upgrades
)
entity
DeferredBlockEntityType<T>
The block entity type this upgrade map belongs to.
upgrades
ImmutableList<Pair<ItemDefinition<UpgradeBase>, Integer>>
Ordered list of (upgrade definition, max slots) pairs that the block entity accepts.

DeferredUpgradeMap

DeferredUpgradeMap is a record that wraps an UpgradeMap inside a DeferredHolder for registration.
public record DeferredUpgradeMap<T extends BasePoweredBlockEntity>(
    Class<? extends BasePoweredBlockEntity> entity,
    DeferredHolder<UpgradeMap<?>, UpgradeMap<T>> holder
) implements Supplier<UpgradeMap<T>>
Call get() to resolve the held UpgradeMap<T> after registration has completed.

CoreUpgrades

CoreUpgrades registers all built-in upgrade items and provides access to upgrade functions.

Built-in upgrades

ConstantDescription
EMPTYPlaceholder base upgrade
SPEEDIncreases machine operation speed
CAPACITYExpands operational size
EFFICIENCYReduces power consumption per operation
OVERCLOCKGreatly increases speed at efficiency cost
THERMAL_BUFFERAllows operation under extreme conditions
AUTO_EJECTORPushes output to connected inventories
INPUT_EXPANDERAccepts input from multiple sides
MULTI_PROCESSOR_UNITEnables multiple simultaneous operations
SILENCING_COILSuppresses machine sounds
NANITE_INJECTORIncreases byproduct and rare drop yield
PRECISION_GEARBOXImproves accuracy for chance-based outputs
REDSTONE_INTERFACEAdds advanced redstone control
ECO_DRIVENear-zero idle power draw
VOID_MODDestroys overflow items
REPLICATION_NODEDuplicates output at high power cost

create() methods

// Register an upgrade with a BiFunction factory (receives Properties and description String)
public static <T extends UpgradeBase, I> ItemDefinition<T> create(
    String id,
    String desc,
    BiFunction<Item.Properties, String, T> factory,
    @Nullable UpgradeFunctionBuilder<T, I> caller
)

// Register an upgrade with a standard Function factory
public static <T extends UpgradeBase, I> ItemDefinition<T> create(
    String id,
    String desc,
    Function<Item.Properties, T> factory,
    @Nullable UpgradeFunctionBuilder<T, I> caller
)

// Explicit ResourceLocation variant (BiFunction)
public static <T extends UpgradeBase, I> ItemDefinition<T> create(
    String name,
    String desc,
    ResourceLocation id,
    BiFunction<Item.Properties, String, T> factory,
    @Nullable UpgradeFunctionBuilder<T, I> caller
)
id / name
String
required
Human-readable upgrade name; used to derive the registry path.
desc
String
required
English description passed to the upgrade’s tooltip.
factory
BiFunction or Function
required
Creates the UpgradeBase (or subclass) item instance.
caller
UpgradeFunctionBuilder
Optional builder that produces an UpgradeFunction. Pass null to register a passive upgrade with no active logic.

getCompatibleUpgrades()

public static ImmutableList<Pair<ItemDefinition<UpgradeBase>, Integer>>
    getCompatibleUpgrades(Block block)
Looks up the UpgradeMap registered for the given block’s entity type and returns its upgrade list. Returns an empty list if no map is registered.
block
Block
required
The block associated with the target block entity.

UpgradeFunctionBuilder and UpgradeFunction

@FunctionalInterface
public interface UpgradeFunctionBuilder<T extends UpgradeBase, I> {
    UpgradeFunction<T, I> build();
}

public interface UpgradeFunction<T extends UpgradeBase, I> {
    // Called once when the upgrade is installed
    void create(T base, I valueType);
    // Called each time the upgraded behavior executes
    void work(I attribute);
}

Code example: implementing Upgradeable in a block entity

import general.mechanics.api.upgrade.Upgradeable;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.items.ItemStackHandler;

public class MyMachineBlockEntity extends BlockEntity implements Upgradeable {

    // Two upgrade slots
    private final ItemStackHandler upgradeInventory = new ItemStackHandler(2);

    public MyMachineBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
        super(type, pos, state);
    }

    @Override
    public ItemStackHandler getUpgradeInventory() {
        return upgradeInventory;
    }

    public void tick() {
        // Check whether a speed upgrade is installed
        var compatibleUpgrades = CoreUpgrades.getCompatibleUpgrades(
            getBlockState().getBlock()
        );
        // Apply upgrade logic as needed ...
    }
}

Build docs developers (and LLMs) love