CurseForge · Minecraft mod
KubeJS PneumaticCraft
KubeJS PneumaticCraft integration
Quick answer
Which KubeJS PneumaticCraft release should I use?
KubeJS PneumaticCraft kubejs_pneumaticcraft-2101.2.1.jar targets 1.21.1 with NeoForge. The project page does not say whether this file belongs on the client, dedicated server, or both. All 4 required mods have matching files.
Where it goes
Is KubeJS PneumaticCraft required on the client, server, or both?
The project page does not say whether this file belongs on the client, dedicated server, or both.
The source does not explicitly classify this release as client-only or server-only.
What else does KubeJS PneumaticCraft kubejs_pneumaticcraft-2101.2.1.jar need?
kubejs_pneumaticcraft-2101.2.1.jar. Change the file and its required mods may change too.
Install KubeJS, PneumaticCraft: Repressurized, Better Advanced Tooltips, Rhino first. We found matching files for this game-version and loader setup. 4 come through another mod in the chain.
4 extra mods were pulled in by other dependencies. Indented rows show who needs each one. We only count dependency files that match this setup. A file for another loader does not fill the gap.
Before you install it
Add KubeJS PneumaticCraft without breaking your instance.
Built for KubeJS PneumaticCraft kubejs_pneumaticcraft-2101.2.1.jar. Pick another file and the loader, install side or required mods may change.
- 01
Stick to this file
Use kubejs_pneumaticcraft-2101.2.1.jar. It targets 1.21.1 with NeoForge; another release may have different loader, side or dependency requirements.
- 02
Bring the mods it needs
Install KubeJS, PneumaticCraft: Repressurized, Better Advanced Tooltips, Rhino first. We found matching files for this game-version and loader setup. 4 come through another mod in the chain.
- 03
Put it on the correct side
The project page does not say whether this file belongs on the client, dedicated server, or both.
- 04
Pick the file you checked
Use the “Get this file” button beside kubejs_pneumaticcraft-2101.2.1.jar. It opens that exact file at the source.
About this project
What does KubeJS PneumaticCraft add?
PneumaticCraft: Repressurized integration for KubeJS. This mod allows you to add and properly edit recipes of PneumaticCraft mod in KubeJS scripts.
Requires KubeJS and PneumaticCraft: Repressurized (both mandatory). Client and server.
NOTE: the writing and examples below are based on Neoforge 1.21.1. See Differences in Forge 1.20.1 at the end for detailed differences.
Supported recipe types (all under event.recipes.pneumaticcraft.):
- pressure_chamber
- explosion_crafting
- assembly_drill
- assembly_laser
- fluid_mixer
- refinery (supports
.minTemp()and.maxTemp()) - thermo_plant (supports
.minTemp()and.maxTemp()) - heat_frame_cooling
- amadron
- fuel_quality
- heat_properties
Note: pressure_chamber_enchanting / pressure_chamber_disenchanting are JEI display pages only (their recipe JSON holds no inputs/outputs), and assembly_drill_laser is generated at runtime from a drill + laser pair — neither can be written.
Object form vs positional args — they are parsed differently, so please read this once:
- Object form,
event.recipes.pneumaticcraft.thermo_plant({ ... }), is parsed with PneumaticCraft's own codecs. Unknown or misspelled keys are silently ignored (exactly like writing raw JSON), but any key this mod does not declare is passed through untouched — that is how you set e.g. amadronwhitelist/blacklist. - Positional args, key functions and the temperature sugar (
.pressure(2.0),.minTemp(373)) go through this mod's own reader: unknown keys are rejected with the list of legal keys, shorthand is accepted, and PneumaticCraft's numeric rules are enforced.
event.recipes.pneumaticcraft.pressure_chamber(results[], inputs[], pressure) results are item stacks (or a single one), inputs are sized ingredients (or a single one: { count: 1, item: 'minecraft:glass' } / { count: 1, tag: 'c:stones' }). pressure is in bar; PneumaticCraft allows -1..20.
event.recipes.pneumaticcraft.explosion_crafting(results[], input, loss_rate) input is a single sized ingredient. loss_rate is 0..99 (20 in the vanilla recipes).
event.recipes.pneumaticcraft.assembly_drill(result, input, program) event.recipes.pneumaticcraft.assembly_laser(result, input, program) result is a single item stack, input a single sized ingredient. program is 'drill' or 'laser' — 'drill_laser' is rejected.
event.recipes.pneumaticcraft.fluid_mixer(input1, input2, fluid_output, item_output, pressure, time) Both inputs are sized fluids: { amount: 25, tag: 'c:plantoil' } or { amount: 25, fluid: 'minecraft:water' } (amount optional, 1000 by default). time is in ticks.
event.recipes.pneumaticcraft.refinery(input, outputs[], temperature?) input is a sized fluid, outputs must be 2 to 4 fluid stacks, temperature defaults to { min: 373 }. Fluid stacks are { amount: 2, id: 'pneumaticcraft:diesel' } — here amount is required (unlike fluid ingredients).
event.recipes.pneumaticcraft.thermo_plant(inputs, outputs, temperature?, pressure?, speed?, air_use_multiplier?, exothermic?) inputs = { fluid: { amount: 100, tag: 'c:diesel' }, item: [] } (item: [] means "no item consumed"; at least one of fluid / item must be present), outputs = { fluid_output: { amount: 80, id: 'pneumaticcraft:kerosene' } } and/or { item_output: { count: 1, id: 'minecraft:glass' } }.
event.recipes.pneumaticcraft.heat_frame_cooling(input, temperature, output, bonusMultiplier?, bonusLimit?) input is either a fluid container { fluid: { amount: 1000, tag: 'minecraft:water' } } — inside it the key is id or tag and amount is required, not fluid — or a normal ingredient. temperature is the threshold in Kelvin.
event.recipes.pneumaticcraft.amadron(offer_id, input, output, level?, static?, villager_trade?, maxStock?, inStock?) Trades are { resource: { count: 1, id: 'minecraft:emerald' } } for items and { resource: { amount: 1000, id: 'pneumaticcraft:diesel' } } for fluids. Positional args also accept a bare id string and work out item vs fluid themselves.
event.recipes.pneumaticcraft.fuel_quality(fluid, air_per_bucket, burn_rate?) fluid is an unsized fluid ingredient: { tag: 'c:diesel' } or { fluid: 'minecraft:water' }. Writing amount here is an error — PneumaticCraft ignores it, so this mod rejects it instead of silently dropping it.
event.recipes.pneumaticcraft.heat_properties(block, temperature, thermalResistance?, heatCapacity?, transforms?, predicates?, description?) transforms = { hot: 'minecraft:lava', cold: 'minecraft:ice', hot_flowing: ..., cold_flowing: ... } (block state strings); predicates = { lit: 'true' } (block state properties — the key really is predicates; the statePredicate seen in some of PneumaticCraft's own files is ignored).
Examples:
event.recipes.pneumaticcraft.pressure_chamber(
[{ count: 1, id: 'minecraft:blue_ice' }],
[{ count: 4, item: 'minecraft:packed_ice' }],
2.5
).id('mypack:pressure/blue_ice')
event.recipes.pneumaticcraft.thermo_plant({
inputs: { fluid: { amount: 100, tag: 'c:diesel' }, item: [] },
outputs: { fluid_output: { amount: 80, id: 'pneumaticcraft:kerosene' } },
pressure: 2.0,
temperature: { min: 573 }
}).id('mypack:thermo/kerosene')
event.recipes.pneumaticcraft.refinery(
{ amount: 10, tag: 'c:crude_oil' },
[
{ amount: 2, id: 'pneumaticcraft:diesel' },
{ amount: 3, id: 'pneumaticcraft:kerosene' }
]
).temperature({ min: 373 }).id('mypack:refinery/crude')
// the same thing with the temperature sugar, plus a max bound:
event.recipes.pneumaticcraft.refinery(
{ amount: 10, tag: 'c:crude_oil' },
[
{ amount: 3, id: 'pneumaticcraft:diesel' },
{ amount: 3, id: 'pneumaticcraft:lpg' }
]
).minTemp(303).maxTemp(333).id('mypack:refinery/crude_warm')
event.recipes.pneumaticcraft.fluid_mixer(
{ amount: 25, tag: 'c:plantoil' },
{ amount: 25, tag: 'c:ethanol' },
{ amount: 50, id: 'pneumaticcraft:biodiesel' },
{ count: 1, id: 'pneumaticcraft:glycerol' },
2.0,
300
).id('mypack:mixer/biodiesel')
event.recipes.pneumaticcraft.assembly_drill(
{ count: 1, id: 'pneumaticcraft:pressure_chamber_valve' },
{ count: 1, item: 'pneumaticcraft:compressed_iron_block' },
'drill'
).id('mypack:assembly/valve')
event.recipes.pneumaticcraft.heat_frame_cooling(
{ fluid: { amount: 1000, tag: 'minecraft:water' } },
273,
{ count: 1, id: 'minecraft:ice' }
).id('mypack:cooling/ice')
event.recipes.pneumaticcraft.amadron({
offer_id: 'mypack:amadron/emerald_to_diesel',
input: { resource: { id: 'minecraft:emerald', count: 1 } },
output: { resource: { id: 'pneumaticcraft:diesel', amount: 1000 } },
level: 0
}).id('mypack:amadron/emerald_to_diesel')
event.recipes.pneumaticcraft.fuel_quality(
{ tag: 'c:my_fuel' },
500000,
1.0
).id('mypack:fuel/my_fuel')
event.recipes.pneumaticcraft.heat_properties({
block: 'minecraft:magma_block',
temperature: 900,
thermalResistance: 1000,
heatCapacity: 500,
transforms: { cold: 'minecraft:netherrack' },
predicates: { lit: 'true' }
}).id('mypack:heat/magma')
Removing and editing PneumaticCraft recipes now works — but always add the type:
event.remove({ type: 'pneumaticcraft:refinery', output: Fluid.of('pneumaticcraft:diesel') })
event.remove({ type: 'pneumaticcraft:amadron', output: 'minecraft:emerald' })
event.remove({ type: 'pneumaticcraft:pressure_chamber', mod: 'pneumaticcraft' })
Note: filters are cross-type, so { output: ... } without type: will also hit recipes from other mods. And for fluid outputs the filter value has to be a fluid, i.e. Fluid.of('pneumaticcraft:diesel') — a plain string is matched as an item and will never match a fluid output.
Note: PneumaticCraft ships 9 fuel_quality recipes, but two of them (ethylene, hydrogen) are gated behind PneumaticCraft's own fluid_tag_present condition, so they only load when some mod provides c:fuels/ethene / c:fuels/hydrogen. A missing tag means the recipe is skipped — that is intended behaviour, not a bug of this mod.
Note: pressure (pressure chamber, -1..20) and loss_rate (explosion crafting, 0..99) are not range-checked by this mod yet; out-of-range values are reported by PneumaticCraft itself.
Mistakes are reported instead of ignored — for example:
# heat_frame_cooling fluid container written with a "fluid" key
pneumaticcraft:fluid_container_ingredient: PnC's heat_frame_cooling fluid input is either(FluidStack, tag+amount)
- the single-fluid key is 'id', not 'fluid' (this is the old trap). Valid keys: [id, tag, amount]
# amount on an unsized fluid ingredient (fuel_quality)
pneumaticcraft:fluid_ingredient_unsized: this PnC field takes an UNSIZED fluid ingredient - PnC ignores 'amount'
here, so it is rejected. Remove it, or use pneumaticcraft:fluid_ingredient for sized fields.
# temperature must be strictly min < max
temperature: min must be < max (PnC rule) - got 400 <= T <= 300
Differences in Forge 1.20.1
Pressure Chamber:
no significant difference.
event.recipes.pneumaticcraft.pressure_chamber(
[Item.of('minecraft:blue_ice')], // ① results
[{ count: 4, item: 'minecraft:packed_ice' }], // ② inputs
2.5 // ③ pressure
).id('mypack:pressure/blue_ice')
Explosion Crafting :
no significant difference.
event.recipes.pneumaticcraft.explosion_crafting(
[Item.of('pneumaticcraft:ingot_iron_compressed')],
{ count: 4, tag: 'forge:storage_blocks/iron' },
20)
Assembly Drill / Assembly Laser:
Output: Use Item.of(...) or {item,count} instead of {count,id} in 1.21.1
// 1.20.1:result → input → program
event.recipes.pneumaticcraft.assembly_drill(
Item.of('minecraft:gold_ingot'),
{ item: 'minecraft:iron_ingot' },
'drill')
Fluid Mixer:
KubeJS 6 (1.20.1 Forge) says required keys must be ahead of optional keys or a IllegalArgumentException will be raised.
// 1.21.1 input1 → input2 → item_output → fluid_output? → pressure → time
event.recipes.pneumaticcraft.fluid_mixer(
{ amount: 25, tag: 'c:plantoil' }, // input1
{ amount: 25, tag: 'c:ethanol' }, // input2
{ amount: 50, id: 'pneumaticcraft:biodiesel' }, // fluid_output(注意是 id)
{ count: 1, id: 'pneumaticcraft:glycerol' }, // item_output
2.0, 300) // pressure, time
// 1.20.1:input1 → input2 → item_output → pressure → time → fluid_output?
event.recipes.pneumaticcraft.fluid_mixer(
{ amount: 25, tag: 'forge:plantoil' },
{ amount: 25, tag: 'forge:ethanol' },
Item.of('pneumaticcraft:glycerol'),
2.0, 300,
{ amount: 50, fluid: 'pneumaticcraft:biodiesel' }) // ← fluid_output OPTIONAL
Refinery:
(1.21.1 → 1.20.1) Output Key : outputs → results Temperature Key : min/max → min_temp/max_temp Fluid Output : id → fluid
// 1.21.1
event.recipes.pneumaticcraft.refinery(
{ amount: 10, tag: 'c:crude_oil' },
[{ amount: 2, id: 'pneumaticcraft:diesel' }, { amount: 3, id: 'pneumaticcraft:kerosene' }], // outputs
{ min: 373 }) // ← min / max
// 1.20.1:input → results → temperature
event.recipes.pneumaticcraft.refinery(
{ amount: 10, tag: 'forge:crude_oil' },
[{ amount: 4, fluid: 'pneumaticcraft:diesel' }, { amount: 4, fluid: 'pneumaticcraft:lpg' }], // ← results!
{ min_temp: 373 }) // ← min_temp / max_temp
.minTemp(393) // min_temp
.maxTemp(473) // max_temp
Thermo Plant:
Completely different.
Argument Order : fluid_input, item_input, fluid_output, item_output, temperature, pressure, speed, air_use_multiplier, exothermic
Input & Output are no longer nested.
the keys are optional except exothermic and you can just write what you want
e.g. P.thermo_plant({amount:100,tag:'...'}, {item:'...'}, {min_temp:423})
// 1.21.1:NESTED
event.recipes.pneumaticcraft.thermo_plant({
inputs: { fluid: { amount: 100, tag: 'c:diesel' }, item: [] },
outputs: { fluid_output: { amount: 80, id: 'pneumaticcraft:kerosene' } },
temperature: { min: 573 },
pressure: 2.0
})
// 1.20.1:FLAT
event.recipes.pneumaticcraft.thermo_plant(
{ amount: 100, tag: 'forge:plantoil' }, // fluid_input
{ item: 'minecraft:potato' }, // item_input
{ amount: 50, fluid: 'minecraft:water' }, // fluid_output
Item.of('pneumaticcraft:chips', 4), // item_output
{ min_temp: 423 }, // temperature
2.0, 1.0, 1.0, false) // pressure, speed, air_use_multiplier, exothermic
Frame Cooling:
(1.21.1 → 1.20.1) temperature → max_temp
output → result
{fluid:…} is no longer used
bonusMultiplier & bonusLimit are not yet supported.
// 1.21.1
event.recipes.pneumaticcraft.heat_frame_cooling({
input: { fluid: { amount: 1000, tag: 'minecraft:water' } }, // ← use fluid
temperature: 273,
output: { count: 1, id: 'minecraft:ice' }
})
// 1.20.1
event.recipes.pneumaticcraft.heat_frame_cooling(
{ amount: 1000, tag: 'minecraft:water' },
273, // ← max_temp rather than temperature
Item.of('minecraft:ice')) // ← result rather than output
Fuel Quality:
amount can be used along with fluid type/tag.
// 1.21.1
event.recipes.pneumaticcraft.fuel_quality(
{ tag: 'c:diesel' }, 999999, 1.0)
// 1.20.1
event.recipes.pneumaticcraft.fuel_quality(
{ amount: 1000, tag: 'forge:biodiesel' }, // ← amount is OK
1000000, 0.8)
Heat Properties :
transforms, predicates, description are not yet supported.
// 1.21.1
event.recipes.pneumaticcraft.heat_properties({
block: 'minecraft:magma_block', temperature: 900,
thermalResistance: 1000, heatCapacity: 500,
transforms: { cold: 'minecraft:netherrack' }, // ← transforms{cold,hot}
predicates: { lit: 'true' }, description: '...'
})
// 1.20.1
event.recipes.pneumaticcraft.heat_properties(
'minecraft:magma_block', 900, 1000.0, 500)
Amadron :
(1.21.1 → 1.20.1) offer_id → id
{resource:{id,count}} → {type,amount,id}
Use amount for both items and fluids , and write capitalized type or FLUID in key type.
// 1.21.1
event.recipes.pneumaticcraft.amadron({
offer_id: 'mypack:emerald_to_diesel',
input: { resource: { id: 'minecraft:emerald', count: 8 } }, // ← resource + count
output: { resource: { id: 'pneumaticcraft:diesel', amount: 1000 } },
level: 0
})
// 1.20.1
event.recipes.pneumaticcraft.amadron(
'mypack/emerald_to_diesel', // ← id only
{ id: 'minecraft:emerald', amount: 8 }, // ← amount for items
{ id: 'pneumaticcraft:diesel', amount: 1000, type: 'FLUID' }, // ← Capitalized type or FLUID
0, true) // level, static
No mixins, no access transformers, no registry changes and no added content — this mod only registers recipe field types with KubeJS, so it can be added or removed at any time without touching your world.
MIT licensed. It references no me.desht.pneumaticcraft.* classes: every rule was read out of PneumaticCraft's sources and re-implemented here, so it neither inherits GPLv3 nor breaks when PneumaticCraft internals change.
Project description from CurseForge.
Pick your setup
KubeJS PneumaticCraft by Minecraft version and loader
Choose the version and loader you play, then open the matching release.
1.21.1
1 loader build1.20.1
1 loader buildCheck the dependencies, then try the file in a copied instance before changing a world you care about.
Recent files
KubeJS PneumaticCraft versions and loaders
kubejs_pneumaticcraft-2101.2.1.jar
8 Oct 2026
kubejs_pneumaticcraft-2001.0.1.jar
kubejs_pneumaticcraft-201.0.1.jar
25 Sept 2026
kubejs_pneumaticcraft-2101.2.0.jar
21 Sept 2026
kubejs_pneumaticcraft-2101.1.0.jar
19 Sept 2026
Looking for an older file? The official CurseForge project page is in Resources.