Mineuniverse
Mods
KubeJS PneumaticCraft

KubeJS PneumaticCraft

MOD
KubeJS PneumaticCraft integration
by IronHammer_Std
Download Claim this project
216 downloads
0 likes
0 followers
Updated Oct 14, 2026
0 hypes
Follow0
KubeJS
Advertisement Remove ads with Premium →

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. amadron whitelist / 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.

kubejs_pneumaticcraft-2101.2.1.jar
MC Client, 1.21.1, NeoForge, Server
Release 2026-10-08 Get
kubejs_pneumaticcraft-2001.0.1.jar
MC Client, 1.20.1, Forge, Server
Alpha 2026-09-25 Get
kubejs_pneumaticcraft-2101.2.0.jar
MC Client, 1.21.1, NeoForge, Server
Release 2026-09-21 Get
kubejs_pneumaticcraft-2101.1.0.jar
MC Client, 1.21.1, NeoForge, Server
Release 2026-09-19 Get
Advertisement Remove ads with Premium →

You Might Also Like