Skip to content

For Mod Developers

CaptainGummiball edited this page Oct 25, 2026 · 1 revision

For Mod Developers

API version 1 · package dev.cptgummiball.quantaworks.api · mod id quantaworks

Most mods need nothing from this page. QuantaWorks uses the standard interfaces of the loader for items, fluids and energy, and Pipster's gas API for gases, so pipes, cables and storage of other mods simply connect. Metals are recognised through the c: tags. This page is for mods and data packs that want to add recipes, materials or rules, or read machines.

QuantaWorks has no own transport API. Every machine exposes the standard interfaces of the loader, so Pipster and every other logistics mod can work with it. Only gases use Pipster's gas API, because neither loader has a gas interface.

Interfaces per version family

Resource Fabric (1.21.1 – 26.3) NeoForge 1.21.1 – 1.21.8 NeoForge 1.21.9 – 26.3
Items ItemStorage.SIDED Capabilities.ItemHandler.BLOCK Capabilities.Item.BLOCK (ResourceHandler<ItemResource>)
Fluids FluidStorage.SIDED, droplets; only whole mB (81 droplets) are moved Capabilities.FluidHandler.BLOCK, mB Capabilities.Fluid.BLOCK (ResourceHandler<FluidResource>), mB
Energy Team Reborn Energy EnergyStorage.SIDED (bundled as jar-in-jar) Capabilities.EnergyStorage.BLOCK (FE) Capabilities.Energy.BLOCK (EnergyHandler, FE)
Gas Pipster GasHandler via BlockApiLookup id pipster:gas_handler Pipster GasHandler via BlockCapability id pipster:gas_handler as 1.21.1 – 1.21.8

Conventions

  • Units: 1 E = 1 FE = 1 Team Reborn Energy unit. Internally energy is a long that saturates; NeoForge int interfaces are clamped per call. Fluids and gases in mB.
  • Energy input of large plants: energy hatches accept at most the rate of their tier (8,000 / 64,000 / 512,000 / 4,096,000 E/t – the Pipster pipe tiers). A plant that needs more uses several hatches fed by separate lines.
  • Directions: machine inputs are insert-only, outputs extract-only. Multiblock ports expose their interface only on the side facing out of the structure, and only while the structure is formed.
  • Simulation: simulations never change state; results never exceed the request; extraction removes only the exact resource (id + components).
  • Gases (pipster:gas domain, unit mB, never fluids): quantaworks:nitrogen, argon, ethylene, ammonia. Hydrogen and oxygen: with QuantaVolt installed QuantaWorks uses quantavolt:hydrogen and quantavolt:oxygen; without QuantaVolt it registers quantaworks:hydrogen and quantaworks:oxygen. Saved contents are migrated between the two when a world gains or loses QuantaVolt.
  • Mekanism chemicals are not compatible (Pipster has no general adapter).
  • Machine readings (CC: Tweaked getReadings(), Jade): energyStored, energyCapacity, energyUsage, energyOutput, burnTime, progress, progressTotal, active, status, recipe, die (Metal Former), pattern (Assembler), batch (copies the running job processes at once, parallel upgrades), areaWidth, areaDepth, rangeUpgrades, yieldUpgrades (field machines) – each machine reports the ones it has. Generators push energy into their neighbours on every side; recipe machines only accept energy.

Data packs

Everything QuantaWorks processes can be added or changed with data packs. Files are read after every data reload (/reload), invalid files are reported in the log and in the material report and never stop the server.

Machine recipes – data/<namespace>/quantaworks/recipe/<path>.json (id <namespace>:<path>)

{
  "type": "quantaworks:pulverizing",
  "conditions": [{"type": "tag_not_empty", "tag": "c:ingots/tin"}, {"type": "mod_loaded", "mod": "example"}],
  "items": [{"tag": "c:ores/tin", "count": 1}],
  "results": [{"tag": "c:dusts/tin", "count": 2}, {"item": "minecraft:gravel", "chance": 0.1}],
  "energy": 40, "duration": 200, "tier": 1, "priority": 0
}

fluids/gases and fluid_results/gas_results take {"fluid"|"gas": id, "amount": mB}; every ingredient may list alternatives as {"any": [...], "count": n}. Tag outputs are resolved to one item (see Representative items). Chances are paid out deterministically (every 10th run for 0.1), never by a random roll. Conditions: mod_loaded, not, all, any, item_exists, fluid_exists, gas_exists, tag_not_empty. A file with the id of a QuantaWorks recipe replaces it; a replacement with "conditions": [{"type": "not", "condition": {"type": "mod_loaded", "mod": "minecraft"}}] switches it off.

Materials – data/<namespace>/quantaworks/material/<name>.json

Materials are recognised from the c: convention tags without any file: c:<form>/<material> with the forms ores, raw_materials, storage_blocks (raw_<material> = raw block), ingots, nuggets, dusts, plates, rods, gears, wires, gems; old-style c:<material>_<forms> tags fill forms the modern tags leave empty (config legacyMaterialTags). A material file adds what tags cannot say:

{
  "schema": 1,
  "material": "exampleium",
  "forms": {"ingot": ["#c:ingots/exampleium", "example:exampleium_bar"], "dust": "example:exampleium_powder"},
  "preferred": {"dust": "example:exampleium_dust"},
  "units": {"rod": 45},
  "byproduct": {"item": "example:shinium_dust", "chance": 0.1},
  "melting_point": 1450,
  "color": "#7fb0d0"
}

Form keys: ore, raw, raw_block, storage_block, ingot, nugget, dust, plate, rod, gear, wire, gem. An item that ends up in two materials or two forms is ambiguous: it is left out of every derived recipe and reported.

Representative items: when several mods make a form, machines produce the preferred item of the material file, otherwise the first item in the namespace order of the server config preferredNamespaces (default minecraft, quantavolt, quantaworks), otherwise the smallest item id.

Processing templates – data/<namespace>/quantaworks/processing_template/<path>.json

A template is applied to every material that has both its input and its result forms and makes one recipe per material (id <namespace>:derived/<path>/<material>):

{
  "schema": 1, "type": "quantaworks:pulverizing", "stage": "derived",
  "input": {"form": "ore", "count": 1},
  "results": [{"form": "dust", "count": 2}],
  "byproduct": true,
  "energy": 40, "duration": 200, "tier": 1
}

stage is derived or fallback (fallbacks can be switched off with fallbackRecipes). QuantaWorks ships the pulverizer templates quantaworks:pulverizing/{ore,raw,raw_block}_to_dust (derived) and {ingot,gem,plate,rod,gear,storage_block}_to_dust (fallback).

Templates may also take fluid inputs and plant requirements: "fluids": [{"fluid": "quantaworks:nitric_acid", "amount": 250}] (ids or #tags) and "requirements": {"columns": 2} – e.g. the Chemical Plant's ore leaching (processing_template/chemical_plant/ore_leaching.json: ore + 250 mB nitric acid → 3 dust + byproduct).

Crop rules – data/<namespace>/quantaworks/crop/<name>.json

{"blocks": ["mod:plant", "#mod:plants"], "type": "age_property", "property": "age"} – tells the Farming Station how to handle a plant it does not know. Types: crop_block, age_property (ripe at the highest value of property, replanted at the lowest), fruit (the block is taken, nothing replanted), column (everything above the base), bush (harvested, back one stage), attached (like age_property, keeps its facing). Without a rule plants are found through CropBlock/CocoaBlock and the block tags quantaworks:crops/age, …/fruit, …/column, …/bush; quantaworks:crops/plantable lists blocks the station may plant from seeds. A replant always uses one seed from the plant's own drops; a plant with growth stages and no adapter is left alone and reported in the screen.

Agricultural Facility – data/<namespace>/quantaworks/growth_profile/<name>.json, block tags quantaworks:beds/...

Plants grow in the facility's beds, never as world blocks. Every plant the Farming Station knows (crop rules and tags above) grows there; the harvest is the loot table of the ripe plant minus one seed for the replant. The time per stage is the vanilla expectation (one random tick per 4096 / 3 ticks, times the plant's chance: crops 1/3, bushes 1/5, sugar cane and cactus 1/16 per piece) divided by the acceleration (×1 – ×8). Plants in block tag quantaworks:beds/soul_sand need a Nether Planter Bed, those in quantaworks:beds/sand a Desert Planter Bed, all others a Planter Bed. Profiles:

  • {"type": "plant", "blocks": ["minecraft:nether_wart", "#mod:plants"], "chance": 0.1, "water": false} – growth chance per random tick and water need;
  • {"type": "tree", "sapling": "minecraft:oak_sapling", "ticks": 24000, "water": true, "results": [{"item": "minecraft:oak_log", "count": 5}, {"item": "minecraft:oak_sapling", "chance": 0.6}]} – a sapling grows for ticks and yields the results; a sapling among them replants the bed (trees cannot be derived safely, so only profiles count). Built in: oak, birch, spruce, jungle, acacia, dark oak, cherry, mangrove.

Plant wall parts from other mods – block tags quantaworks:multiblock/casing, quantaworks:multiblock/glass

A block in one of these tags counts as Industrial Casing or Viewport in every QuantaWorks plant (e.g. a mod's reinforced glass as a viewport). Energy enters plants only through Energy Hatches (tier 2 – 5: 8,000 / 64,000 / 512,000 / 4,096,000 E per tick each, whatever is connected); each plant allows a limited number of hatches.

Foundry alloys – data/<namespace>/quantaworks/alloy/<name>.json

{"parts": {"copper": 3, "tin": 1}, "result": "bronze", "min_temperature": 950, "inert_gas": false}: material keys and their ratio in material units (MU). In a Foundry whose bath holds every part and is at least min_temperature (°C) hot, whole sets turn into the result (at most 10 sets per tick, MU conserved). inert_gas: true needs argon in the Foundry's gas hatch (1 mB per set). An alloy whose metals the pack lacks never forms, and neither does one whose result has no ingot in the pack (it could never be cast). The melting point and bath colour of a material come from melting_point and color in its material file (default 1,200 °C). Built in: bronze, brass, electrum, invar, constantan.

Plant wall parts from other mods – block tags (Foundry)

In addition to casing and glass, the tag quantaworks:multiblock/refractory accepts other blocks as Foundry walls. Induction coils and casting basins are functional parts and only the QuantaWorks blocks count.

Assembler blocklist – data/<namespace>/quantaworks/not_automatable/<name>.json

{"recipes": ["minecraft:some_recipe", ...]}: crafting recipes the Assembler never automates (in addition to the server config assemblerBlockedRecipes). Results or remainders with item components are refused as well.

Process types of the tier I machines

quantaworks:pulverizing, quantaworks:induction_smelting (every mod's smelting recipes are imported automatically; alloys with two inputs), quantaworks:pressing, rolling, gear_forming, wire_drawing, compacting (Metal Former, chosen by the inserted die), quantaworks:plant_processing, quantaworks:assembly (Assembler without a pattern card).

Tier II: quantaworks:air_separation (no input), quantaworks:chemical_reaction (Chemical Reactor, and the Chemical Plant – one batch per reactor column), quantaworks:centrifuging, quantaworks:crystallizing.

Assembly Complex: quantaworks:assembly recipes run on every station; a precision recipe names the station it needs with "requirements": {"station:laser_welder": 1} (station types robot_arm, press, laser_welder, soldering, inspection). Step recipes quantaworks:assembly_line list their stations in order – "steps": ["press", "soldering", "inspection"] – and run only when the line has those stations in that order (other stations may lie between); the workpiece rides the conveyor from station to station and the line runs it alone. Java API: recipes().assemblyLine(id) .steps("press", "soldering", "inspection"). With a pattern library, the 27 pattern cards in the controller are crafted one per station at a time (the game's real crafting recipes, as in the Assembler).

Particle Processing Facility: quantaworks:particle_processing with "requirements": {"beam_energy": 1000} – the beam energy a run needs. A ring reaches 100 × cavities (at most one cavity per four beam-line blocks), reduced when it has fewer focusing magnets than one per eight beam-line blocks; the edge-9 ring of the blueprint reaches 500, edge 33 reaches 2,900. The beam ramps up before a run advances and costs 500,000 × (beam / 500)^1.55 E/t while it is held (the facility draws it; the recipe's energy is ignored). Built in: exotic matter (500), echo shard (800), charged quantum crystal (1000), stabilized matter (1500), nether star (2500).

Quantum Facility: quantaworks:quantum_fabrication runs only in a stable coherence field (built once with 5·10⁹ E, held with 250,000 E/t and 1 mB liquid nitrogen per second; a field that is not held warns for 100 ticks and then collapses, its charge lost). The recipe's energy comes on top of the field (built in: quantum processor, field emitter, field stabilizer, speed and efficiency upgrades). The quantum frame is a step recipe through the Assembly Complex's Quantum Manipulator station (quantum_manipulator, 64,000 E/t).

Machine upgrades (speed, efficiency, parallel; range and yield for field machines): see Upgrades.

Matter Reconstructor – data/<namespace>/quantaworks/reconstruction_rule/<name>.json: {"target": "gold", "form": "ingot", "from": ["ingot", "dust"], "ratio": 4, "exclude": ["netherite"], "energy": 1000000, "duration": 200, "scan_energy": 1000000000} – every family with a source form turns into the target, ratio times the target's material units in (at least 1: never a gain; whole pieces, rounded up). The recipes are derived (quantaworks:reconstruction) and pass the balance check with all others. Explicit quantaworks:reconstruction recipes name "requirements": {"scan_energy": ...}. Every target needs its pattern: the scanner writes it onto a blank Matter Pattern once (the target's scan energy, 1 – 5·10⁹ E); patterns are items in the pattern slots. Items with components are never an input. Built in: any metal to gold (ratio 4) and to iron (ratio 2), coal blocks to diamond, netherrack to netherite scrap.

Deep Core Extractor – data/<namespace>/quantaworks/deep_core/<name>.json per dimension: {"dimension": "minecraft:overworld", "enabled": true, "weights": {"minecraft:diamond_ore": 2, "#c:ores/coal": 0.5}, "add": {"minecraft:ancient_debris": 4}}. Without any file the Deep Core brings up what the dimension's ore features place (every mod's ore features too, after biome modifications), weighted by vein size × veins per chunk, averaged over the dimension's biomes, and only items in c:ores. weights multiply (0 removes), add puts in ores without a feature, enabled: false switches the dimension off; rules apply in id order. Every ore block costs deepCoreEnergyPerOre (default 2·10⁷ E), 25 mB liquid nitrogen and one use of a drill head (2,048 uses); the tower height (12 – 20) sets the depth (1 – 9) and with it the power (0.5 – 2 M E/t); each depth step is lowered once (2.5·10⁸ E). Regions of 128 × 128 blocks hold deepCoreRegionReserve ores (default 50,000) for all extractors in them.

Plants: quantaworks:chemical_plant – the Chemical Plant's exclusive large processes. Such a recipe runs alone on the whole plant and needs "requirements": {"columns": N} reactor columns (built in: fast ammonia synthesis, cracking of plant oil, ore leaching 3× as a processing template). When one can start, running reactions finish and no new ones start.

Resolution order and balance

For the same input the first source wins: explicit recipe files → Java API → vanilla recipes → derived → fallback; within a source the higher priority, then the more specific input, then the id. Material units: nugget 10, ingot/dust/raw/plate 90, rod/wire 45, gear 360, block 810, ore 180 (per material in units). A template may never produce ore or raw ore, nor more units than it takes (except from ore and raw ore). After every reload all recipes are checked for loops that create material; derived recipes in such a loop are switched off, explicit ones are reported (and switched off with strictBalance). /quantaworks materials report (operators) writes everything to quantaworks/materials-report.txt.

Java API v1 (quantaworks-api-1.jar, Minecraft-free)

quantaworks-api-1.jar and quantaworks-api-1-javadoc.jar are attached to the GitHub releases. Compile against the API jar only (compileOnly, never shade it or ship QuantaWorks files); QuantaWorks brings the classes at runtime. If QuantaWorks is optional for your mod, check that the mod quantaworks is loaded before touching its classes. The API has no Minecraft classes, so one jar serves every Minecraft version and both loaders. The license allows compiling against the API and publishing mods that use it.

// in your mod initialiser (Fabric onInitialize, NeoForge mod constructor)
QuantaWorksApi.materials().family("example:exampleium")
    .form(MaterialForm.ORE, "#c:ores/exampleium").form(MaterialForm.INGOT, "#c:ingots/exampleium")
    .form(MaterialForm.DUST, "#c:dusts/exampleium").meltingPoint(1450).byproduct("example:shinium", 0.10).register();
QuantaWorksApi.recipes().pulverizing("example:crush_shard")
    .input("#c:gems/example_shard", 1).output("example:shard_dust", 2).energy(40).duration(120).register();
QuantaWorksApi.conditions().register("example:in_overworld", ctx -> ctx.dimension().equals("minecraft:overworld"));
QuantaWorksApi.listeners().add(new ProcessListener() { public void onFinish(ProcessEvent e) { /* … */ } });
Part Use
QuantaWorksApi.recipes() recipe(type, id) and shortcuts (pulverizing, inductionSmelting, pressing, rolling, gearForming, wireDrawing, compacting, plantProcessing, assembly); builder: input, inputAny, fluid, gas, output (with chance), fluidOutput, gasOutput, energy (E/t), duration, tier, priority, requirement, condition, register()
QuantaWorksApi.materials() family("ns:material") – forms (MaterialForm or the data key), preferred, units, meltingPoint, color, byproduct
QuantaWorksApi.conditions() register(id, ProcessCondition); a recipe naming it (condition(id) / JSON "process_conditions") only starts while it holds. ProcessContext: machine, recipe, dimension, position, day time, rain. An unknown condition never holds
QuantaWorksApi.listeners() ProcessListener: onStart, onFinish, onFail(reason); onFormed/onCollapsed for plants
MachineQuery lookup id quantaworks:machine_query – Fabric BlockApiLookup<MachineQuery, Direction>, NeoForge sided BlockCapability<MachineQuery, Direction>; info() gives MachineInfo (machine id, energy, usage, progress, active, status, recipe)

Rules (checked): registration only during mod initialisation – QuantaWorks freezes the API when the server starts, later calls throw IllegalStateException ("frozen"). Ids are namespaced and unique (a second registration throws). Amounts must be positive, chances in (0, 1], tiers 1–4; unknown forms throw. Nothing is silently adjusted. API recipes are rebuilt with every data reload (tags resolve like in data packs); a data pack file with the same id wins; a recipe whose output does not exist in the pack is skipped. Listeners and conditions run on the server thread; their exceptions are logged and never stop a machine.

Stability

QuantaWorksApi.API_VERSION changes with every incompatible change of dev.cptgummiball.quantaworks.api. Everything else is internal.

Clone this wiki locally