diff --git a/src/java/mmm/materials/MAlloyRecipe.java b/src/java/mmm/materials/MAlloyRecipe.java
index 4069428..328de06 100644
--- a/src/java/mmm/materials/MAlloyRecipe.java
+++ b/src/java/mmm/materials/MAlloyRecipe.java
@@ -56,6 +56,7 @@ public class MAlloyRecipe
 		private int burnTime;
 		private float xp;
 		private ItemStack output;
+		private int slag;
 		private final ItemStack[] inputs = new ItemStack[ MAlloyRecipe.MAX_ALLOY_INPUTS ];
 		private int nInputs;
 
@@ -75,6 +76,9 @@ public class MAlloyRecipe
 
 		public MAlloyRecipe.Builder setBurnTime( final int burnTime )
 		{
+			if ( burnTime <= 0 ) {
+				throw new IllegalArgumentException( "invalid burn time" );
+			}
 			this.burnTime = burnTime;
 			return this;
 		}
@@ -82,6 +86,9 @@ public class MAlloyRecipe
 
 		public MAlloyRecipe.Builder setExperience( final float xp )
 		{
+			if ( xp < 0 ) {
+				throw new IllegalArgumentException( "invalid experience" );
+			}
 			this.xp = xp;
 			return this;
 		}
@@ -122,6 +129,16 @@ public class MAlloyRecipe
 		}
 
 
+		public MAlloyRecipe.Builder setSlag( final int slag )
+		{
+			if ( slag < 0 ) {
+				throw new IllegalArgumentException( "invalid amount of slag" );
+			}
+			this.slag = slag;
+			return this;
+		}
+
+
 		public MAlloyRecipe.Builder addInput( final Item item )
 		{
 			return this.addInput( new ItemStack( item ) );
@@ -185,8 +202,8 @@ public class MAlloyRecipe
 				inputs[ i ] = this.inputs[ i ].copy( );
 			}
 
-			final MAlloyRecipe recipe = new MAlloyRecipe( this.name , this.burnTime , this.xp , this.output.copy( ) ,
-					inputs );
+			final MAlloyRecipe recipe = new MAlloyRecipe( this.name , this.burnTime , this.xp , this.slag ,
+					this.output.copy( ) , inputs );
 			registry.byName.put( this.name , recipe );
 			registry.list.add( recipe );
 			this.name = null;
@@ -215,16 +232,18 @@ public class MAlloyRecipe
 	public final ResourceLocation name;
 	public final int burnTime;
 	public final float xp;
+	public final int slag;
 	public final ItemStack output;
 	public final ItemStack[] inputs;
 
 
-	private MAlloyRecipe( final ResourceLocation name , final int burnTime , final float xp , final ItemStack output ,
-			final ItemStack[] inputs )
+	private MAlloyRecipe( final ResourceLocation name , final int burnTime , final float xp , final int slag ,
+			final ItemStack output , final ItemStack[] inputs )
 	{
 		this.name = name;
 		this.burnTime = burnTime;
 		this.xp = xp;
+		this.slag = slag;
 		this.output = output;
 		this.inputs = inputs;
 	}
@@ -264,4 +283,14 @@ public class MAlloyRecipe
 		return true;
 	}
 
+
+	public int getTotalInputItems( )
+	{
+		int sum = 0;
+		for ( int i = 0 ; i < this.inputs.length ; i++ ) {
+			sum += this.inputs[ i ].stackSize;
+		}
+		return sum;
+	}
+
 }
diff --git a/src/java/mmm/materials/Materials.java b/src/java/mmm/materials/Materials.java
index dc63afb..5b14b27 100644
--- a/src/java/mmm/materials/Materials.java
+++ b/src/java/mmm/materials/Materials.java
@@ -4,6 +4,7 @@ package mmm.materials;
 import mmm.materials.ore.MOCopper;
 import mmm.materials.ore.MOCuprite;
 import mmm.materials.ore.MOMalachite;
+import mmm.utils.I_URecipeRegistrar;
 import mmm.utils.URegistry;
 import net.minecraft.block.material.MapColor;
 import net.minecraft.creativetab.CreativeTabs;
@@ -14,12 +15,14 @@ import net.minecraft.item.Item;
 
 
 public class Materials
+		implements I_URecipeRegistrar
 {
 
 	public static final MMetal GOLD;
 	public static final MMetal IRON;
 	public static final MMetal COPPER;
 
+	public static final Item ITEM_SLAG;
 	public static final Item ITEM_MALACHITE;
 	public static final Item ITEM_CUPRITE;
 	public static final Item ITEM_COKE;
@@ -38,18 +41,18 @@ public class Materials
 		COPPER = new MMetal( "copper" , 0.4f , 4f , 1 , MapColor.DIRT );
 
 		// Items that do not correspond to metals or ores
+		URegistry.addItem( ITEM_SLAG = Materials.makeItem( "slag" ) );
 		URegistry.addItem( ITEM_MALACHITE = Materials.makeItem( "malachite" ) );
 		URegistry.addItem( ITEM_CUPRITE = Materials.makeItem( "cuprite" ) );
-		URegistry.addItem( ITEM_COKE = Materials.makeFuel( "coke" , 4800 ) );
+		URegistry.addItem( ITEM_COKE = Materials.makeFuel( "coke" , 9600 ) );
 
 		// Actual ores
 		URegistry.addBlock( ORE_COPPER = new MOCopper( ) );
 		URegistry.addBlock( ORE_MALACHITE = new MOMalachite( ) );
 		URegistry.addBlock( ORE_CUPRITE = new MOCuprite( ) );
 
-		// Alloy recipes
-		MAlloyRecipe.build( ).setName( "materials/coke" ).setBurnTime( 1600 ).setExperience( 0.1f )
-				.setOutput( ITEM_COKE ).addInput( Items.COAL ).register( );
+		// Other recipes
+		URegistry.addRecipeRegistrar( new Materials( ) );
 	}
 
 
@@ -75,4 +78,19 @@ public class Materials
 		// EMPTY
 	}
 
+
+	private Materials( )
+	{
+		// EMPTY
+	}
+
+
+	@Override
+	public void registerRecipes( )
+	{
+		// Alloy recipes
+		MAlloyRecipe.build( ).setName( "materials/coke" ).setBurnTime( 3200 ).setExperience( 0.1f )
+				.addInput( Items.COAL , 2 ).setOutput( ITEM_COKE ).setSlag( 1 ).register( );
+	}
+
 }
diff --git a/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java b/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java
index fc3ff26..4e2e21c 100644
--- a/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java
+++ b/src/java/mmm/tech/base/TBAlloyFurnaceTileEntity.java
@@ -2,6 +2,7 @@ package mmm.tech.base;
 
 
 import mmm.materials.MAlloyRecipe;
+import mmm.materials.Materials;
 import mmm.utils.UInventoryGrid;
 import net.minecraft.block.state.IBlockState;
 import net.minecraft.item.ItemStack;
@@ -111,7 +112,10 @@ public class TBAlloyFurnaceTileEntity
 			if ( this.alloying != null ) {
 				this.alloyCurrent--;
 				if ( this.alloyCurrent == 0 ) {
-					this.addOutput( );
+					this.addOutput( this.alloying.output );
+					if ( this.alloying.slag != 0 ) {
+						this.addOutput( new ItemStack( Materials.ITEM_SLAG , this.alloying.slag ) );
+					}
 					if ( this.canAlloy( ) ) {
 						this.startAlloying( );
 					} else {
@@ -123,7 +127,7 @@ public class TBAlloyFurnaceTileEntity
 			if ( this.burnCurrent == 0 ) {
 				if ( this.alloying != null ) {
 					if ( !this.startBurning( this.alloyCurrent ) ) {
-						// XXX produce slag
+						this.addOutput( new ItemStack( Materials.ITEM_SLAG , this.alloying.getTotalInputItems( ) ) );
 						this.alloying = null;
 						this.alloyCurrent = this.burnCurrent = this.burnTotal = 0;
 					}
@@ -324,9 +328,8 @@ public class TBAlloyFurnaceTileEntity
 	}
 
 
-	private void addOutput( )
+	private void addOutput( ItemStack wanted )
 	{
-		final ItemStack wanted = this.alloying.output;
 		final int maxStackSize = Math.min( this.output.getInventoryStackLimit( ) , wanted.getMaxStackSize( ) );
 		int added = 0;
 		for ( int i = 0 ; i < this.output.slotsCount ; i++ ) {
diff --git a/src/java/mmm/tech/base/TechBase.java b/src/java/mmm/tech/base/TechBase.java
index 92317cf..bd0f21f 100644
--- a/src/java/mmm/tech/base/TechBase.java
+++ b/src/java/mmm/tech/base/TechBase.java
@@ -32,7 +32,7 @@ public class TechBase
 		URegistry.addServerMessage( TBAlloyFurnaceMessage.class );
 
 		// FIXME test, remove this later
-		MAlloyRecipe.build( ).setName( "test" ).setBurnTime( 50 ).setExperience( .05f )
+		MAlloyRecipe.build( ).setName( "test" ).setBurnTime( 50 ).setExperience( .05f ).setSlag( 1 )
 				.setOutput( Items.COOKED_CHICKEN , 10 ).addInput( Items.COOKED_BEEF ).addInput( Items.COOKED_PORKCHOP )
 				.register( );
 	}
diff --git a/src/resources/assets/mmm/models/item/materials/stone/slag.json b/src/resources/assets/mmm/models/item/materials/stone/slag.json
new file mode 100644
index 0000000..6003248
--- /dev/null
+++ b/src/resources/assets/mmm/models/item/materials/stone/slag.json
@@ -0,0 +1,6 @@
+{
+    "parent": "minecraft:item/generated",
+    "textures": {
+        "layer0": "mmm:items/materials/stone/slag"
+    }
+}
\ No newline at end of file
diff --git a/src/resources/assets/mmm/textures/items/materials/stone/slag.png b/src/resources/assets/mmm/textures/items/materials/stone/slag.png
new file mode 100644
index 0000000..dc8da00
Binary files /dev/null and b/src/resources/assets/mmm/textures/items/materials/stone/slag.png differ