diff --git a/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java b/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java
index fb79d2f1e..ebea485b6 100644
--- a/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java
+++ b/src/main/java/net/minecraft/core/block/ChainlinkFenceBlock.java
@@ -17,7 +17,7 @@ public class ChainlinkFenceBlock extends ThinFenceBlock
     public boolean canConnectTo(WorldSource world, int x, int y, int z)
     {
         int id = world.getBlockId(x, y, z);
-        return Block.hasTag(id, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[id] != null && (Block.blocksList[id].blockMaterial.isStone() || Block.blocksList[id].blockMaterial == Material.metal));
+        return Block.hasTag(id, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[id] != null && (Block.blocksList[id].blockMaterial.isStone() || Block.blocksList[id].blockMaterial.isMetal()));
     }
     
     @Override
diff --git a/src/main/java/net/minecraft/core/block/FireBlock.java b/src/main/java/net/minecraft/core/block/FireBlock.java
index 22f11aecf..ee4ee476b 100644
--- a/src/main/java/net/minecraft/core/block/FireBlock.java
+++ b/src/main/java/net/minecraft/core/block/FireBlock.java
@@ -2,6 +2,7 @@ package net.minecraft.core.block;
 
 import net.minecraft.core.block.entity.BlockEntity;
 import net.minecraft.core.block.tag.BlockTags;
+import net.minecraft.core.data.gamerule.GameRules;
 import net.minecraft.core.sound.SoundCategory;
 import net.minecraft.core.util.phys.AABB;
 import net.minecraft.core.block.material.Material;
@@ -111,7 +112,7 @@ public class FireBlock extends Block {
 	@Override
 	public void updateTick(World world, int x, int y, int z, Random rand) {
 		Block blockUnder = world.getBlock(x, y - 1, z);
-		boolean infiniBurn = blockUnder != null && blockUnder.hasTag(BlockTags.INFINITE_BURN);
+		boolean infiniBurn = blockUnder != null && blockUnder.hasTag(BlockTags.INFINITE_BURN) || !world.getGameRuleValue(GameRules.DO_FIRE_SPREAD);
 
 		//Extinguish fire
 		if (!isValidFireLocation(world, x, y, z)) {
@@ -182,7 +183,7 @@ public class FireBlock extends Block {
 						continue;
 					}
 					
-					if(getBurnResultId(world, x1, y1, z1) == 0 /* Fix for fire destroying moss blocks */) {
+					if(world.getGameRuleValue(GameRules.DO_FIRE_SPREAD) && getBurnResultId(world, x1, y1, z1) == 0 /* Fix for fire destroying moss blocks */) {
 						//Spread Fire with higher meta
 						world.setBlockAndMetadataWithNotify(x1, y1, z1, id, Math.min(meta + rand.nextInt(5) / 4, 15));
 					}
@@ -195,6 +196,7 @@ public class FireBlock extends Block {
 	}
 
 	private void checkBurn(World world, int x, int y, int z, int chance, Random random, int meta) {
+		if (!world.getGameRuleValue(GameRules.DO_FIRE_SPREAD)) return;
 		if (random.nextInt(chance) < burnChance[world.getBlockId(x, y, z)]) {
 			boolean isTNT = world.getBlockId(x, y, z) == Blocks.TNT.id;
 			
diff --git a/src/main/java/net/minecraft/core/block/SteelFenceBlock.java b/src/main/java/net/minecraft/core/block/SteelFenceBlock.java
index 3dba8a56f..5d84e70cd 100644
--- a/src/main/java/net/minecraft/core/block/SteelFenceBlock.java
+++ b/src/main/java/net/minecraft/core/block/SteelFenceBlock.java
@@ -12,6 +12,6 @@ public class SteelFenceBlock extends ThinFenceBlock {
     @Override
     public boolean canConnectTo(WorldSource world, int x, int y, int z) {
         int id = world.getBlockId(x, y, z);
-        return Block.hasTag(id, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[id] != null && (Block.blocksList[id].blockMaterial.isStone() || Block.blocksList[id].blockMaterial == Material.metal));
+        return Block.hasTag(id, BlockTags.CHAINLINK_FENCES_CONNECT) || (Block.blocksList[id] != null && (Block.blocksList[id].blockMaterial.isStone() || Block.blocksList[id].blockMaterial.isMetal()));
     }
 }
diff --git a/src/main/java/net/minecraft/core/block/TorchBlock.java b/src/main/java/net/minecraft/core/block/TorchBlock.java
index b3ca58fc7..3fb4e37ea 100644
--- a/src/main/java/net/minecraft/core/block/TorchBlock.java
+++ b/src/main/java/net/minecraft/core/block/TorchBlock.java
@@ -54,7 +54,13 @@ public class TorchBlock extends Block
 
     private boolean canPlaceOnTop(World world, int x, int y, int z)
     {
-        return canPlaceBlockAt(world, x, y, z);
+        int blockBelow = world.getBlockId(x, y, z);
+        return world.canPlaceOnSurfaceOfBlock(x, y, z)
+            || blockBelow == Blocks.FENCE_PLANKS_OAK.id
+            || blockBelow == Blocks.FENCE_PLANKS_OAK_PAINTED.id
+            || blockBelow == Blocks.FENCE_CHAINLINK.id
+            || blockBelow == Blocks.FENCE_PAPER_WALL.id
+            || blockBelow == Blocks.FENCE_STEEL.id;
     }
 
     @Override
@@ -76,13 +82,7 @@ public class TorchBlock extends Block
         {
             return true;
         }
-        int blockBelow = world.getBlockId(x, y - 1, z);
-        return world.canPlaceOnSurfaceOfBlock(x, y - 1, z)
-            || blockBelow == Blocks.FENCE_PLANKS_OAK.id
-            || blockBelow == Blocks.FENCE_PLANKS_OAK_PAINTED.id
-            || blockBelow == Blocks.FENCE_CHAINLINK.id
-            || blockBelow == Blocks.FENCE_PAPER_WALL.id
-            || blockBelow == Blocks.FENCE_STEEL.id;
+        return canPlaceOnTop(world, x, y - 1, z);
     }
 
     @Override
diff --git a/src/main/java/net/minecraft/core/block/material/Material.java b/src/main/java/net/minecraft/core/block/material/Material.java
index 7797f31d0..8bb721e26 100644
--- a/src/main/java/net/minecraft/core/block/material/Material.java
+++ b/src/main/java/net/minecraft/core/block/material/Material.java
@@ -17,6 +17,7 @@ public class Material
     public final MaterialColor color;
     private boolean alwaysDestroyable;
     private boolean isStone;
+    private boolean isMetal;
     private int pushReaction = PISTON_PUSHABLE;
     private int lightningConductivity = LIGHTNING_NEUTRAL;
 
@@ -53,6 +54,15 @@ public class Material
 
     public boolean isStone() { return isStone; }
 
+    public Material setAsMetal() {
+        isMetal = true;
+        return this;
+    }
+
+    public boolean isMetal() {
+        return isMetal;
+    }
+
     public Material notSolidBlocking()
     {
         notSolidBlocking = true;
@@ -143,8 +153,8 @@ public class Material
     public static final Material slate = new Material(MaterialColor.slate).setConductivity(LIGHTNING_LIGHT_INSULATOR).setAsStone().notAlwaysDestroyable();
     public static final Material netherrack = new Material(MaterialColor.netherrack).setConductivity(LIGHTNING_LIGHT_INSULATOR).setAsStone().notAlwaysDestroyable();
 
-    public static final Material metal = new Material(MaterialColor.metal).setConductivity(LIGHTNING_STRONG_CONDUCTOR).notAlwaysDestroyable();
-    public static final Material steel = new Material(MaterialColor.steel).setConductivity(LIGHTNING_STRONG_CONDUCTOR).notAlwaysDestroyable();
+    public static final Material metal = new Material(MaterialColor.metal).setConductivity(LIGHTNING_STRONG_CONDUCTOR).setAsMetal().notAlwaysDestroyable();
+    public static final Material steel = new Material(MaterialColor.steel).setConductivity(LIGHTNING_STRONG_CONDUCTOR).setAsMetal().notAlwaysDestroyable();
     public static final Material water = new LiquidMaterial(MaterialColor.water).setConductivity(LIGHTNING_LIGHT_CONDUCTOR).destroyOnPush();
     public static final Material lava = new LiquidMaterial(MaterialColor.fire).destroyOnPush();
     public static final Material leaves = new Material(MaterialColor.plant).flammable().notSolidBlocking().destroyOnPush();
diff --git a/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java b/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java
index a9b82a586..21723967b 100644
--- a/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java
+++ b/src/main/java/net/minecraft/core/block/piston/SteelPistonBaseBlock.java
@@ -21,6 +21,8 @@ import java.util.List;
 public class SteelPistonBaseBlock extends PistonBaseBlock{
     public static final double HEAD_THICKNESS_STEEL = 6/16d;
 
+    private Entity flungBlock = null;
+
     public SteelPistonBaseBlock(String key, String namespaceId, int id, int maxPushedBlocks) {
         super(key, namespaceId, id, maxPushedBlocks);
     }
@@ -113,6 +115,9 @@ public class SteelPistonBaseBlock extends PistonBaseBlock{
                 if (rider != null) rider.startRiding(fallingBlockEntity);
             }
             world.entityJoinedWorld(fallingBlockEntity);
+            final double speed = 2;
+            fallingBlockEntity.fling(direction.getOffsetX() * speed, direction.getOffsetY() * speed, direction.getOffsetZ() * speed, 1f);
+            flungBlock = fallingBlockEntity;
         }
         return true;
     }
@@ -134,10 +139,11 @@ public class SteelPistonBaseBlock extends PistonBaseBlock{
     public void extendEvent(World world, int x, int y, int z, int data, Direction direction) {
         List<Entity> entityList = new ArrayList<>(world.getEntitiesWithinAABBExcludingEntity(null, AABB.getTemporaryBB((double)x + direction.getOffsetX(), (double)y + direction.getOffsetY(), (double)z + direction.getOffsetZ(), (double)x + direction.getOffsetX() + 1, (double)y + direction.getOffsetY() + 1, (double)z + direction.getOffsetZ() + 1)));
         for (Entity entity : entityList){
-            if (entity == null || entity.noPhysics) continue;
+            if (entity == null || entity.noPhysics || entity == flungBlock /*Fix for 1 tick extensions not working properly*/ ) continue;
             final double speed = 2;
             entity.fling(direction.getOffsetX() * speed, direction.getOffsetY() * speed, direction.getOffsetZ() * speed, 1f);
         }
+        flungBlock = null;
         super.extendEvent(world, x, y, z, data, direction);
     }
 
diff --git a/src/main/java/net/minecraft/core/data/gamerule/GameRules.java b/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
index ef514cbfc..8c0210fae 100644
--- a/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
+++ b/src/main/java/net/minecraft/core/data/gamerule/GameRules.java
@@ -14,6 +14,7 @@ public abstract class GameRules
     public static GameRuleBoolean MOB_GRIEFING = register(new GameRuleBoolean("mobGriefing", true));
     public static GameRuleBoolean DO_DAY_CYCLE = register(new GameRuleBoolean("doDaylightCycle", true));
     public static GameRuleBoolean DO_WEATHER_CYCLE = register(new GameRuleBoolean("doWeatherCycle", true));
+    public static GameRuleBoolean DO_FIRE_SPREAD = register(new GameRuleBoolean("doFireSpread", true));
     public static GameRuleBoolean INSTANT_HEALING = register(new GameRuleBoolean("instantHealing", false));
 
     public static <T extends GameRule<?>> T register(T gameRule)
