Script the machine processing recipes of Industrial Upgrade (IU) from KubeJS.
IU has two completely separate recipe systems:
| Crafting recipes | Machine processing recipes | |
|---|---|---|
| Where | datapack data/industrialupgrade/recipe/*.json |
Java memory: com.denfop.api.recipe.RecipesCore.map_recipes |
| Example | crafting a machine block | crushing ore, making ME storage components |
| Recipe id | yes | no |
| Editable from KubeJS | yes (ServerEvents.recipes) |
not at all |
So pack authors run into dead ends like these:
event.remove({ id: 'industrialupgrade:...' }) cannot delete a crusher recipe - it is not a datapack recipe.event.replaceInput(...) silently does nothing to IU's custom recipe types; KubeJS falls back to a no-op implementation for recipe types it has no schema for.This mod exposes IU's internal recipe API as plain static methods that KubeJS (or any other mod) can call through Java.loadClass.
// kubejs/startup_scripts/iu_machine.js -- must be startup_scripts
StartupEvents.postInit(event => {
const iu = Java.loadClass('com.kubejsiu.recipe.IURecipeBridge')
// Crusher: ender pearl -> ender dust
iu.addItemRecipe('macerator', 'minecraft:ender_pearl', 1, 'ae2:ender_dust', 1)
// Multi-slot machine with temperature: chip maker (5 slots)
iu.addMultiRecipe('microchip',
['ae2:cell_component_1k', 'ae2:certus_quartz_crystal',
'industrialupgrade:itemdust/silicon_dust', 'industrialupgrade:itemingots/osmium',
'industrialupgrade:itemingots/yttrium'],
[1, 1, 1, 1, 1],
'ae2:cell_component_4k', 1, 0, 4500)
})
/kubejs_iu machines list every machine name, slot count and recipe count
/kubejs_iu recipes macerator list all recipes of one machine
/kubejs_iu dump write the full machine list to the log
Machine names are matched literally and a typo is ignored silently, so always check the name first.
Add recipes
| Method | Notes |
|---|---|
addItemRecipe(machine, in, inCount, out, outCount) |
single item to item |
addItemRecipeTag(machine, tag, inCount, out, outCount) |
accepts tags like #c:plates/iron; one recipe per tag member |
addMachineRecipe(machine, in, inCount, out, outCount, energy) |
with energy cost |
addMultiRecipe(machine, ids[], counts[], out, outCount[, energy][, temperature]) |
multi-slot machines |
addFluidRecipe(machine, inFluid, inMb, outFluid, outMb) |
fluid machines |
addFluidItemRecipe(machine, fluid, mb, in, inCount, out, outCount) |
fluid + item to item |
addCentrifugeRecipe(in, inCount, out, outCount) |
thermal centrifuge |
addSeedBagRecipe(in, cropId) |
compressor seed bags |
Inspect
listMachines() - describeMachine(machine) - countRecipes(machine) - listRecipes(machine) - dumpMachines()
Remove and replace
| Method | Notes |
|---|---|
removeByInput(machine, in, inCount) |
removes recipes whose first input matches |
removeByOutput(machine, out, outCount) |
removes recipes producing that item |
clearMachine(machine) |
wipes the machine (items and fluids), returns how many were removed |
removeFluidRecipe(machine) |
wipes only that machine's fluid recipes |
replaceItemRecipe(machine, ...) - replaceFluidRecipe(machine, ...) |
clear, then register |
reloadRecipes(className) |
re-runs the default recipes of a registration class (take the class name, not the machine name) |
Every method returns false / 0 and logs a warning on failure instead of throwing into KubeJS.
StartupEvents.postInit in kubejs/startup_scripts/. IU's recipe table already exists at that point, and addRecipe appends - putting this in server_scripts would duplicate recipes on every /reload./reload does not re-run startup scripts.energy / temperature values of 0 mean "use the machine default".