ServerEvents.recipes(event => {
	// Metal tiers:
	// Copper, iron, tin, nickel, gold, zinc, brass, invar, bronze - Pre-basic build tier, the only ores that don't require a pulverizer or smelter to process
	// gold, silver, lead - gated behind crushing wheels
	// platinum, iridum, osmium - Gated behind the pulverizer
	// lumium, enderium, electrum, signalum, steel - Alloys are gated behind the smelter as well
	// uranium - requires basic energetic grist to energize into ingots

	// Gear tiers:
	// copper, iron, tin, nickel, zinc, brass, bronze - Pre-gear die tier
	// invar, bronze, brass - the only alloys you can make without grist
	// constantan - requires 1 build grist to make the dust alloy
	// invar, gold, silver, electrum, signalum, lead, steel - Gated behind gear die
	// lumium, enderium, other alloys - Gated behind heavy duty gear die

	let metalForm = (metal, tag, form) => {
		let itemType = AlmostUnified.getPreferredItemForTag(`forge:${tag}/${metal}`);
		if (itemType.id == 'minecraft:air') {
			console.log(`metals: ${metal} ${form} has unknown tag forge:${tag}/${metal}?`)
			let ret = Item.of(`alltheores:${metal}_${form}`);
			if (ret.id == "minecraft:air") {
				return Item.of(`thermal:${metal}_${form}`);
			}
			return ret;
		}
		console.log(`metals: forge:${tag}/${metal} found`);
		return itemType;
	}

	// Progression
	// Vanilla age -> Ore hammer for crushing tin to make andesite alloy
	// Andesite age -> Mixer from andesite allow allows creating early alloys: bronze, brass, invar, constantan
	// Invar age -> induction smelter from invar gears (which now require grist) allows higher level alloys: constantan
	// Alloy age -> Higher level alloys unlock the rest of Thermal

	// New metal tiers:
	// Primitive: Copper - The only ore you can smelt directly in an oven. Also can be processed in a crafting table.
	// Vanilla: Iron, tin, nickel, gold, zinc, brass, bronze, invar - The ores require a ore hammer to create 2x crushed ore, which can be smelted into ingots. The metals can be processed in a crafting table.
	// Modded (requires build grist): invar

	// Progression recipes:
	// Constantan:

	/*

	Metal progression:
		Primitive tier: Stone pickaxe to mine, raw ore can be immediately smelted
			Copper
		Vanilla tier: Stone pickaxe to mine, ore hammer to crush, then smelted. Only one alloy, and it can be crated on the crafting table
			Iron, Tin, Gold, Zinc: Ores
			Andesite alloy: 2x andesite + tin dust
			Progression: Find tin, crush it, create andesite alloy to start making create mod items
		Andesite age: Iron pickaxe to mine, crushing wheels to crush, then the crushed ore is smelted normally. Alloys require the create mixer. Ore washing to double crushed ore is unlocked, but fans require invar instead of iron. Gears can be crafted on a crafting table
			Silver, Aluminium, Lead: Ores
			Bronze - tin + copper
			Brass - tin + 3x copper
			Rose gold - copper + gold
			Progression: Make some brass, craft a gear on the crafting table with build grist, create an induction furnace
		Mechanical/grist age: Ores require diamond pick, crushed in the pulverizer, and crushed ore is smelted normally. Alloys require the induction furnace. 4x ore centrifuge is unlocked after creating a constantan gear on the crafting table. Other gears require the press.
			Uranium, Platinum, Iridium?, Nickel, Osmium
			Electrum - gold + silver
			Invar - 2x iron + nickel
			Constantan - Copper + nickel
			Netherite - 4x netherite scrap, 4x gold
			Progression: Create the gear die
		Industrial age: Alloys require basic grists, gears can only be made with a gear die
			Redium - 4x redstone powder, 2x obsidian powder, 2x iron dust, 1x blaze
			Lapium - 4x lapis powder, 2x gold dust, 2x obsidian powder, 1x quartz powder
			Gemium - 2x diamond, 1x prismarine powder, 2x emerald dust, 4x obsidian powder
			Trilium - 2x lapium, 4x gemium, 1x ender powder, 2x redium
			Signalum - silver + 3x copper + 4x redstone
			Lumium - silver + 3x tin + 2x glowstone dust
			Progression: Make it to the nether
		Modern age: Alloys require improved grist
			Gobber - gobber glob + diamond + iron + gold
			nether gobber - nether glob + 2x gobber + netherite scrap
			Quadrilium - 4x trilium, 4x netherite scrpa, 1x ghast tear
			Progression: Make it to the end
		Age of Legends:
			Enderium - 1x diamond + 3x lead + 2x ender pearl = 2 ingot
			end gobber - end glob + 2x nether gobber + chorus flower
			Progression: That's it, that's the end. You won the game.
	*/

	let progression = {
		// Primitive tier: Stone pickaxe to mine, raw ore can be immediately smelted
		primitive: {
			copper: []
		},
		// Vanilla tier: Stone pickaxe to mine, ore hammer to crush, then smelted. Only one alloy, and it can be crated on the crafting table
		vanilla: {
			iron: [],
			tin: [],
			gold: [],
			zinc: [],
			// FIXME: Need to add create:andesite_alloy to #forge:ingots/andesite_alloy
			andesite_alloy: [4, '2x minecraft:andesite', 'tin']
		},
		// Andesite age: Iron pickaxe to mine, crushing wheels to crush, then the crushed ore is smelted normally. Alloys require the create mixer. Ore washing to double crushed ore is unlocked, but fans require invar instead of iron. Gears can be crafted on a crafting table
		andesite: {
			silver: [],
			aluminum: [],
			lead: [],
			rose_gold: [2, 'copper', 'gold'],
			bronze: [2, 'tin', 'copper'],
			constantan: [2, 'copper', 'nickel'],
			brass: [2, 'zinc', 'copper']
		},
		// Mechanical/grist age: Ores require diamond pick, crushed in the pulverizer, and crushed ore is smelted normally. Alloys require the induction furnace. 4x ore centrifuge is unlocked after creating a constantan gear on the crafting table. Other gears require the press.
		mechanical: {
			nickel: [],
			invar: [3, '2x iron', 'nickel'],
			electrum: [2, 'gold', 'silver'],
			netherite: [1, '4x minecraft:netherite_scrap', '4x gold'],
		},
		// Industrial age: Alloys require basic grists, gears can only be made with a gear die
		industrial: {
			steel: [2, '2x iron', '#minecraft:coals'],
			uranium: [],
			platinum: [],
			osmium: [],
			signalum: [4, 'silver', '3x copper', '4x minecraft:redstone'],
			lumium: [4, 'silver', '3x tin', '2x minecraft:glowstone_dust'],
			redium: [4, '4x powder_power:powder_redstone', '2x #forge:dusts/obsidian', '2x #forge:dusts/iron', 'minecraft:blaze_powder'],
			lapium: [4, '4x powder_power:powder_lapis', '2x #forge:dusts/gold', '2x #forge:dusts/obsidian', 'powder_power:powder_nether_quartz'],
			gemium: [4, '4x #forge:dusts/obsidian', '2x #forge:dusts/diamond', '2x #forge:dusts/emerald', 'powder_power:powder_prismarine'],
			trilium: [4, '2x lapium', '2x gemium', '2x redium', 'powder_power:powder_end_pearl']
		},
		// Modern age: Alloys require improved grist
		modern: {
			gobber: [3, 'gobber2:gobber2_glob', 'platinum', 'osmium'],
			nether_gobber: [3, 'gobber2:gobber2_glob_nether', 'minecraft:netherite_scrap', '2x gobber'],
			quadrilium: [3, '3x trilium', '4x minecraft:netherite_scrap', 'powder_power:powder_ghast_tear']
		},
		// Age of Legends: The end game
		legends: {
			//enderium: [],
			end_gobber: [3, 'gobber2:gobber2_glob_end', '2x nether_gobber', '2x #kubejs:grist/build/improved']
		}
	};

	// Basic rules for all materials
	for (const [key, metals] of Object.entries(progression)) {
		for (const [metal, ingredients] of Object.entries(metals)) {
			let rawType = metalForm(metal, 'raw_materials', 'ore');
			let crushedType = Item.of(`create:crushed_raw_${metal}`);

			let dustType = metalForm(metal, 'dusts', 'dust');
			let nuggetType = metalForm(metal, 'nuggets', 'nugget');
			let ingotType = metalForm(metal, 'ingots', 'ingot');
			let blockType = metalForm(metal, 'storage_blocks', 'block');
			let rawBlockType = metalForm(`raw_${metal}`, 'storage_blocks', 'block');

			let plateType = metalForm(metal, 'plates', 'plate');
			let gearType = metalForm(metal, 'gears', 'gear');
			let rodType = metalForm(metal, 'rods', 'rod');

			console.log(`Wiping out stock ore processing for ${metal}...`);

			// Wipe out all the stock recipes
			event.remove({output: gearType});
			event.remove({output: dustType});
			event.remove({output: blockType});
			event.remove({output: rodType});
			event.remove({output: plateType});
			event.remove({output: ingotType});
			event.remove({output: rawBlockType});
			event.remove({output: nuggetType});
			event.remove({output: crushedType});
			event.remove({input: crushedType});

			// All dusts and crushed ores can be smelted to ingots, and made with ore hammers
			if (dustType.id != 'minecraft:air') {
				event.smelting(ingotType, dustType);
				event.shapeless(dustType, [ingotType, '#alltheores:ore_hammers']);
			}

			// Plates can always be smelted back into their original ingot
			if (plateType.id != 'minecraft:air') {
				event.smelting(ingotType, plateType);
				// 1 plate = 1 ingot in presses
				event.recipes.thermal.press(plateType, [ingotType]);
				event.recipes.create.pressing([plateType], [ingotType]);
			}

			// 4 ingots = 1 gear
			if (gearType.id != 'minecraft:air') {
				event.recipes.thermal.press(gearType, [ingotType.withCount(4), 'thermal:press_gear_die']);
			}

			// 9 Nuggets == 1 ingot, for every material
			if (nuggetType.id != 'minecraft:air') {
				event.shapeless(ingotType, [nuggetType.withCount(9)]);
				event.shapeless(nuggetType.withCount(9), [ingotType]);
			}
			// 9 ore = 1 ore block
			if (rawType.id != 'minecraft:air') {
				event.shapeless(rawBlockType, [rawType.withCount(9)]);
				event.shapeless(rawType.withCount(9), [rawBlockType]);
			}
			// 9 ingots = 1 block
			if (blockType.id != 'minecraft:air') {
				event.shapeless(blockType, [ingotType.withCount(9)]);
				event.shapeless(ingotType.withCount(9), [blockType]);
			}

			// All alloys can be created in the smelter, or a superheated mixer
			if (ingredients.length > 0) {
				for (const form of ['ingots', 'dusts']) {
					let real_ingredients = [];
					for (const ingredient of ingredients.slice(1)) {
						let real_item = Item.of(ingredient);
						if (real_item.id == 'minecraft:air') {
							let parts = ingredient.split(' ');
							if (parts.length == 1) {
								real_item = metalForm(parts[0], form);
							} else {
								real_item = metalForm(parts[1], form).withCount(parts[0].split('x')[0]);
							}
						}

						if (real_item.id == 'minecraft:air') {
							console.error(`Unknown or invalid ${metal} alloy ingredient: ${ingredient}`);
						}
						real_ingredients.push(real_item);
					}

					if (real_ingredients.length > 0) {
						if (real_ingredients.length <= 3) {
							event.recipes.thermal.smelter(ingotType.withCount(ingredients[0]), real_ingredients);
						} else {
							event.recipes.create.mixing(ingotType.withCount(ingredients[0]), real_ingredients).superheated();
						}
					}
				}
			}
			// TODO: Create saw, 3x3 packing/unpacking dies, mechanical press
		}
	}

	// Primitive tier: Ores can be immediately smelted
	for (const [metal, ingredients] of Object.entries(progression.primitive)) {
		let ingotType = metalForm(metal, 'ingots', 'ingot');
		let rawType = metalForm(metal, 'raw_materials', 'ore');
		let rawBlockType = metalForm(`raw_${metal}`, 'storage_blocks', 'block');
		let blockType = metalForm(metal, 'storage_blocks', 'block');

		console.log(`Building primitive processing for ${metal}...`);

		if (rawType.id != 'minecraft:air') {
			event.smelting(ingotType, rawType);
			event.smelting(blockType, rawBlockType);
		} else {
			console.error(`No ${metal} smelting available!`);
		}

		// There are no alloys here to handle...
	}
	// The progression item is simply creating a copper ore hammer

	// Vanilla tier: Ores need an ore hammer, and alloys can be crafted on the crafting table
	for (const tier of ['primitive', 'vanilla']) {
		for (const [metal, ingredients] of Object.entries(progression[tier])) {
			let rawType = metalForm(metal, 'raw_materials', 'ore');
			let dustType = metalForm(metal, 'dusts', 'dust');
			let ingotType = metalForm(metal, 'ingots', 'ingot');
			let rawBlockType = metalForm(`raw_${metal}`, 'storage_blocks', 'block');

			console.log(`Building vanilla processing for ${metal}...`);

			// Crush raw ore into dust with an ore hammer, in crafting table and in the deployer
			if (rawType.id != 'minecraft:air') {
				event.shapeless(dustType, [rawType, '#alltheores:ore_hammers']);
				event.shapeless(dustType.withCount(9), [rawBlockType, '#alltheores:ore_hammers']);
				event.recipes.create.deploying([dustType], [rawType, '#alltheores:ore_hammers']).keepHeldItem();
				event.recipes.create.deploying([dustType.withCount(9)], [rawBlockType, '#alltheores:ore_hammers']).keepHeldItem();
			} else {
				console.error(`No ${metal} ore hammer smashing available!`);
			}

			// TODO: alloy ingredients
			for (const form of ['ingots', 'dusts']) {
				let real_ingredients = [];
				for (const ingredient of ingredients.slice(1)) {
					let real_item = Item.of(ingredient);
					if (real_item.id == 'minecraft:air') {
						let parts = ingredient.split(' ');
						if (parts.length == 1) {
							real_item = metalForm(parts[0], form);
						} else {
							real_item = metalForm(parts[1], form).withCount(parts[0].split('x')[0]);
						}
					}
					
					if (real_item.id == 'minecraft:air') {
						console.error(`Unknown or invalid ${metal} alloy ingredient: ${ingredient}`);
					} else {
						real_ingredients.push(real_item);
					}
				}

				if (real_ingredients.length > 0) {
					event.shapeless(ingotType.withCount(ingredients[0]), real_ingredients);
				}
			}
		}
	}
	// Andesite alloy is the progression item, as it unlocks most of the next tier of create
	event.shapeless('create:andesite_alloy', [global.dustItem('tin'), '2x minecraft:andesite']);

	// Andesite age: Crushing wheels to crush, then the crushed ore is smelted normally. Alloys require the create mixer. Ore washing to double crushed ore is unlocked, but fans require invar instead of iron. Gears can be crafted on a crafting table
	for (const tier of ['primitive', 'vanilla', 'andesite']) {
		for (const [metal, ingredients] of Object.entries(progression[tier])) {
			let rawType = metalForm(metal, 'raw_materials', 'ore');
			let crushedType = Item.of(`create:crushed_raw_${metal}`);
			let dustType = metalForm(metal, 'dusts', 'dust');
			let ingotType = metalForm(metal, 'ingots', 'ingot');
			let rawBlockType = metalForm(`raw_${metal}`, 'storage_blocks', 'block');
			let gearType = metalForm(metal, 'gears', 'gear');
			let plateType = metalForm(metal, 'plates', 'plate');

			console.log(`Building andesite processing for ${metal}...`);

			if (rawType.id != 'minecraft:air') {
				if (crushedType.id != 'minecraft:air') {
					event.recipes.create.crushing([crushedType.withCount(2)], rawType);
					event.recipes.create.crushing([crushedType.withCount(18)], rawBlockType);
					event.recipes.create.milling([crushedType.withCount(2)], rawType);
					event.recipes.create.milling([crushedType.withCount(18)], rawBlockType);
					event.smelting(ingotType, crushedType);

					if (dustType.id != 'minecraft:air') {
						event.recipes.create.splashing([dustType.withCount(2)], crushedType);
					} else {
						console.error(`No ${metal} ore washing available!`);
					}
				} else {
					console.error(`No ${metal} ore crushing available!`);
				}
			}

			if (gearType.id != 'minecraft:air') {
				event.shaped(gearType, [
					' A ',
					'ABA',
					' A '
				], {
					'A': ingotType,
					'B': '#forge:gems'
				});
			} else {
				console.error(`No ${metal} gears available!`);
			}

			if (plateType.id != 'minecraft:air') {
				event.shapeless(plateType, [ingotType.withCount(2), '#alltheores:ore_hammers']);
			} else {
				console.error(`No ${metal} plates available!`);
			}

			// TODO: alloy ingredients
			for (const form of ['ingots', 'dusts']) {
				let real_ingredients = [];
				for (const ingredient of ingredients.slice(1)) {
					let real_item = Item.of(ingredient);
					if (real_item.id == 'minecraft:air') {
						let parts = ingredient.split(' ');
						if (parts.length == 1) {
							real_item = metalForm(parts[0], form);
						} else {
							real_item = metalForm(parts[1], form).withCount(parts[0].split('x')[0]);
						}
					}
					
					if (real_item.id == 'minecraft:air') {
						console.error(`Unknown or invalid ${metal} alloy ingredient: ${ingredient}`);
					}
					real_ingredients.push(real_item);
				}

				if (real_ingredients.length > 0) {
					event.recipes.create.mixing(ingotType.withCount(ingredients[0]), real_ingredients).heated();
				}
			}
		}
	}
	// Most machines from here on out require nickel, so we unlock the pulverizer behind our early alloys
	event.replaceInput(
		{output: 'thermal:machine_pulverizer'},
		'#forge:gears/copper',
		global.gearItem('brass')
	);

	// Mechanical/grist age: Ores require diamond pick, crushed in the pulverizer, and crushed ore is smelted normally. Alloys require blending dusts in a heated mixer, then smelting the blend. 4x ore centrifuge is unlocked after creating a constantan gear on the crafting table. Other gears require the press.
	for (const tier of ['primitive', 'vanilla', 'andesite', 'mechanical']) {
		for (const [metal, ingredients] of Object.entries(progression[tier])) {
			let rawType = metalForm(metal, 'raw_materials', 'ore');
			let crushedType = Item.of(`create:crushed_raw_${metal}`);
			let dustType = metalForm(metal, 'dusts', 'dust');
			let ingotType = metalForm(metal, 'ingots', 'ingot');

			console.log(`Building mechanical processing for ${metal}...`);

			if (rawType.id != 'minecraft:air') {
				if (crushedType.id != 'minecraft:air') {
					// Crushed ores are created in the industrial tier code, but mechanical tier and below are the only ones that don't need a centrifuge first
					// This allows Nickel to be processed into a constantan gear, which unlocks the centrifuge
					event.smelting(ingotType, [crushedType]);
				} else {
					console.error(`No ${metal} ore pulverizing available! Falling back to dust-based processing line`);
				}
			}

			for (const form of ['dusts']) {
				let real_ingredients = [];
				for (const ingredient of ingredients.slice(1)) {
					let real_item = Item.of(ingredient);
					if (real_item.id == 'minecraft:air') {
						let parts = ingredient.split(' ');
						if (parts.length == 1) {
							real_item = metalForm(parts[0], form);
						} else {
							real_item = metalForm(parts[1], form).withCount(parts[0].split('x')[0]);
						}
					}

					if (real_item.id == 'minecraft:air') {
						console.error(`Unknown or invalid ${metal} alloy ingredient: ${ingredient}`);
					}
					real_ingredients.push(real_item);
				}

				if (real_ingredients.length > 0) {
					event.recipes.create.mixing(dustType.withCount(ingredients[0]), real_ingredients).heated();
				}
			}
		}
	}
	// Constantan gear is the progression item to get to the industrial tier, as it unlocks the press (and therefore other gears)

	// Industrial age: Ores require centrifuging, alloys require basic grists, gears can only be made with a gear die
	for (const tier of ['primitive', 'vanilla', 'andesite', 'mechanical', 'industrial']) {
		for (const [metal, ingredients] of Object.entries(progression[tier])) {
			let rawType = metalForm(metal, 'raw_materials', 'ore');
			let crushedType = Item.of(`create:crushed_raw_${metal}`);
			let dustType = metalForm(metal, 'dusts', 'dust');
			let rawBlockType = metalForm(`raw_${metal}`, 'storage_blocks', 'block');
			if (rawType.id != 'minecraft:air') {
				if (crushedType.id != 'minecraft:air') {
					event.recipes.thermal.pulverizer([crushedType.withCount(4), crushedType.withChance(0.25)], rawType);
					event.recipes.thermal.pulverizer([crushedType.withCount(4 * 9), crushedType.withChance(0.25)], rawBlockType);
					event.recipes.thermal.centrifuge([dustType.withCount(4), dustType.withChance(0.25)], crushedType);
				} else {
					console.error(`No ${metal} ore centrifuing available!`);
				}
			}
		}
	}
});

function foobar() {
	event.shapeless('thermal:quartz_dust', ['8x minecraft:granite', '#alltheores:ore_hammers']).id('kubejs:quartz_dust_from_granit_crushing_manual_only');
	event.shapeless('thermal:quartz_dust', ['minecraft:quartz', '#alltheores:ore_hammers']).id('kubejs:quartz_dust_crushing_manual_only');

	// All metals can be processed in the pulverizer/crusher, make plates in the press, and make gears with the die
	{
	let _ = ['copper', 'rose_gold', 'aluminum', 'constantan', 'iron', 'tin', 'nickel', 'gold', 'zinc', 'brass', 'invar', 'bronze', 'silver', 'platinum', 'lead', 'iridium', 'osmium', 'lumium', 'enderium', 'electrum', 'signalum', 'steel', 'uranium'].forEach(metal => {
		console.log(`Setting up Tier 3 ${metal} processing...`);

		let gearType = metalForm(metal, 'gears', 'gear');
		let dustType = metalForm(metal, 'dusts', 'dust');
		let plateType = metalForm(metal, 'plates', 'plate');
		let ingotType = metalForm(metal, 'ingots', 'ingot');
		let rawType = metalForm(metal, 'raw_materials', 'ore');
		let blockType = metalForm(`raw_${metal}`, 'storage_blocks', 'block');
		let crushedType = Item.of(`create:crushed_raw_${metal}`);

		event.remove({output: gearType});
		event.remove({output: plateType});
		
		event.remove({input: `#forge:ores/${metal}`});
		event.remove({input: `#forge:raw_materials/${metal}`});

		// By default, you can't make any blends in the crafting table.
		event.remove({output: dustType, type: 'minecraft:crafting'});
		event.remove({output: ingotType, input: 'minecraft:fire_charge'});

		// Remove the default conversion of ingot to nuggets from create
		event.remove({input: ingotType, type: 'create:crushing'});

		// And completely eliminate the default refining line with create crushed ores
		if (crushedType.id != 'minecraft:air') {
			event.remove({input: crushedType});
			event.remove({output: crushedType});
		} else {
			console.log(`metals: Missing create:crushed_raw_${metal}`);
		}

		event.remove({id: `alltheores:${metal}_dust_from_alloy_blending`});

		console.log(`crushing ${rawType.toJson()} ${dustType.toJson()}`);
		if (rawType.id != "minecraft:air") {
			event.custom({
				type: "thermal:pulverizer",
				ingredients: [
					{tag: `forge:raw_materials/${metal}`}
				],
				result: [
					{item: dustType.id, chance: 1.05},
					{item: dustType.id, chance: 0.25}
				],
				experience: 0.5
			});

			if (crushedType.id != 'minecraft:air') {
				event.custom({
					type: "create:crushing",
					ingredients: [
						{tag: `forge:raw_materials/${metal}`}
					],
					results: [
						{item: crushedType.id, chance: 1},
						{item: crushedType.id, chance: 0.25},
						{item: dustType.id, chance: 0.05},
						{item: 'create:experience_nugget', count: 2, chance: 0.75}
					],
				});
			}
		}

		if (blockType.id != "minecraft:air") {
			event.custom({
				type: "thermal:pulverizer",
				ingredients: [
					{tag: `forge:storage_blocks/raw_${metal}`}
				],
				result: [
					{item: dustType.id, count: 9, chance: 1},
					{item: dustType.id, count: 9, chance: 0.25}
				],
				experience: 0.5
			});

			if (crushedType.id != 'minecraft:air') {
				event.custom({
					type: "create:crushing",
					ingredients: [
						{tag: `forge:storage_blocks/raw_${metal}`}
					],
					results: [
						{item: crushedType.id, count: 9, chance: 1},
						{item: crushedType.id, count: 9, chance: 0.25},
						{item: dustType.id, count: 9, chance: 0.05},
						{item: 'create:experience_nugget', count: 2 * 9, chance: 0.75}
					],
				});
			}
		}

		// Set up the parallel create-based ore washing line
		if (crushedType.id != 'minecraft:air') {
			event.custom({
				type: "create:splashing",
				ingredients: [
					{item: crushedType.id }
				],
				results: [
					{item: dustType.id, count: 2, chance: 1},
					{item: dustType.id, chance: 0.25},
					{item: dustType.id, chance: 0.05},
				],
			});

			event.custom({
				type: "thermal:centrifuge",
				ingredients: [
					{item: crushedType.id }
				],
				result: [
					{item: dustType.id, count: 3, chance: 3.0},
					{item: dustType.id, chance: 0.75},
					{item: "twigs:pebble", chance: 0.05}
				],
			});
		}

		// 1 dust = 1 ingot
		event.custom({
			type: "thermal:pulverizer",
			ingredients: [
				ingotType.toJson()
			],
			result: [
				dustType.toJson()
			],
		});

		event.custom({
			type: "create:crushing",
			ingredients: [
				ingotType.toJson()
			],
			results: [
				dustType.toJson()
			],
		});

		// 4 ingots = 1 gear
		event.custom({
			type: "thermal:press",
			ingredients: [
				ingotType.withCount(4).toJson(),
				{ item: "thermal:press_gear_die" }
			],
			result: [gearType.toJson()]
		});

		// 1 ingot = 1 plate
		event.custom({
			type: "thermal:press",
			ingredients: [
				ingotType.toJson(),
			],
			result: [plateType.toJson()]
		});
		event.custom({
			type: "create:pressing",
			ingredients: [
				ingotType.toJson(),
			],
			results: [plateType.toJson()]
		});
	});}

	// But only these metals can be processed without a machine
	{let _ = ['copper', 'iron', 'tin', 'nickel', 'zinc', 'brass', 'bronze', 'lead', 'aluminum'].forEach(metal => {
		console.log(`Setting up ${metal} manual processing...`);
		let gearID = metalForm(metal, 'gears', 'gear');
		let plateID = metalForm(metal, 'plates', 'plate');
		let dustID = metalForm(metal, 'dusts', 'dust');
		event.shaped(gearID, [
			' A ',
			'ABA',
			' A '
		], {
			'A': global.ingotItem(metal),
			'B': '#forge:gems'
		});
		event.shapeless(plateID, [global.ingotItem(metal, 2), '#alltheores:ore_hammers']).id(`kubejs:plate_crushing_${metal}_manual_only`);
		event.shapeless(dustID, [global.ingotItem(metal), '#alltheores:ore_hammers']).id(`kubejs:ore_crushing_${metal}_manual_only`);
	});}

	// And only these ores can be hammered or crushed
	{let _ = ['copper', 'iron', 'tin', 'nickel', 'zinc', 'lead', 'aluminum', 'gold'].forEach(ore => {
		console.log(`Setting up ${ore} hammering...`);
		let dustType = metalForm(ore, 'dusts', 'dust');
		event.shapeless(dustType.withCount(2), [`#forge:raw_materials/${ore}`, '#alltheores:ore_hammers']).id(`kubejs:ore_crushing_2_${ore}_manual_only`);
		event.shapeless(dustType.withCount(2 * 9), [`#forge:storage_blocks/raw_${ore}`, '#alltheores:ore_hammers']).id(`kubejs:ore_block_crushing_${ore}_manual_only`);
	});}

	// And only copper can be smelted without pulverizing
	event.smelting(global.ingotItem('copper'), metalForm('copper', 'raw_materials', 'ore'));

	console.log(`Setting up blends...`);
	// These are the only blends you can make by hand, aka pre-smelter alloys
	// FIXME: Remove the hammer from the create mixer
    event.shapeless(Item.of(metalForm('bronze', 'dusts', 'dust').withCount(4)), [
		global.dustItem('tin', 2), 
		global.dustItem('copper', 2),
		'#alltheores:ore_hammers'
	]).id('kubejs:bronze_mixing_manual_only');
	event.custom({
		type: "create:mixing",
		ingredients: [
			global.dustItem('tin', 2),
			global.dustItem('copper', 2),
		],
		results: [global.dustItem('tin', 4)]
	});

	event.shapeless(Item.of(metalForm('brass', 'dusts', 'dust').withCount(4)), [
		global.dustItem('copper', 3),
		global.dustItem('zinc', 1),
		'#alltheores:ore_hammers'
	]).id(`kubejs:brass_mixing_manual_only`);
	event.custom({
		type: "create:mixing",
		ingredients: [
			global.dustItem('copper', 3),
			global.dustItem('zinc', 1),
		],
		results: [global.dustItem('brass', 4)]
	});

	event.shapeless(Item.of(metalForm('invar', 'dusts', 'dust').withCount(4)), [
		global.dustItem('iron', 2),
		global.dustItem('nickel', 2),
		'#alltheores:ore_hammers'
	]).id('kubejs:invar_mixing_manual_only');
	event.custom({
		type: "create:mixing",
		ingredients: [
			global.dustItem('iron', 2),
			global.dustItem('nickel', 2),
		],
		results: [global.dustItem('invar', 4)]
	});

	// Constantan dust consumes your first build grist, and it unlocks the basic grist production line
	event.shapeless(Item.of(metalForm('constantan', 'dusts', 'dust').withCount(4)),[
		global.ingotItem('nickel', 2),
		global.ingotItem('copper', 2),
		'#kubejs:grist/build/basic',
		'#alltheores:ore_hammers'
	]).id('kubejs:constantan_dust_mixing_manual_only');
	// Constantan is the only metal you can't work on the bench except for gears
	event.shaped('thermal:constantan_gear', [
        ' A ',
        'ABA',
        ' A '
    ], {
        'A': global.ingotItem('constantan'),
        'B': '#forge:gems'
    });

	event.shaped('thermal:diamond_gear', [
		' A ',
		'ABA',
		' A '
	], {
		'A': 'minecraft:diamond',
		'B': 'minecraft:crying_obsidian'
	});
	
	// Lapis can be pulverized and hammered.
	event.remove({output: 'thermal:lapis_dust', type: 'thermal:pulverizer'});
	event.custom({
		type: "thermal:pulverizer",
		ingredients: [
			{ item: "minecraft:lapis_lazuli" }
		],
		result: [
			{ item: "thermal:lapis_dust", chance: 1.05 },
			{ item: "thermal:lapis_dust", chance: 0.25 }
		],
		experience: 0.5
	});
	event.shapeless("2x thermal:lapis_dust", ["minecraft:lapis_lazuli", '#alltheores:ore_hammers']).id('kubejs:lapis_dust_crushing_manual_only');

	// Create clay by centrifuging gravel and ash bricks
	event.custom({
		type: "thermal:centrifuge",
		ingredients: [
			{ item: "supplementaries:ash_brick" }
		],
		result: [
			{ item: "minecraft:clay_ball", chance: 1.05 },
			{ item: "minecraft:clay_ball", chance: 0.25 }
		],
		experience: 0.5
	});

	event.custom({
		type: "thermal:centrifuge",
		ingredients: [
			{ item: "minecraft:gravel" }
		],
		result: [
			{ item: "minecraft:sand", chance: 2.00 },
			{ item: "minecraft:clay_ball", chance: 0.75 }
		],
		experience: 0.5
	});
}