diff --git a/change_spawn_interval_tick.sh b/change_spawn_interval_tick.sh
deleted file mode 100755
index 01e91f815dcbe4b134918d58687ae4a32cf56af7..0000000000000000000000000000000000000000
--- a/change_spawn_interval_tick.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-for file in $(ls *.json)
-do
-	echo "sed 's/^.*spawnIntervalTick.*$/      \"spawnIntervalTicks\": 600,/g' ${file} | tee ${file}"
-done
diff --git a/pom.xml b/pom.xml
old mode 100755
new mode 100644
index e65414bcae2a4ad9d7da9a4e9f8833e2b5c04c78..11d70363fe0253a387bc3be3956d30b8ca6336a9
--- a/pom.xml
+++ b/pom.xml
@@ -112,6 +112,12 @@
             <version>4.11</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.9.5</version>
+        </dependency>
+
         <dependency>
             <groupId>com.google.http-client</groupId>
             <artifactId>google-http-client</artifactId>
diff --git a/src/main/java/com/comandante/creeper/ConfigureCommands.java b/src/main/java/com/comandante/creeper/ConfigureCommands.java
old mode 100755
new mode 100644
index 480300f4ad359ae1e4d5d6aa83b2c650145266b2..dc186d2f089ce6a54e64c55eae29e875ab50d242
--- a/src/main/java/com/comandante/creeper/ConfigureCommands.java
+++ b/src/main/java/com/comandante/creeper/ConfigureCommands.java
@@ -5,8 +5,10 @@ import com.comandante.creeper.command.UnknownCommand;
 import com.comandante.creeper.command.admin.*;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.merchant.bank.commands.*;
-import com.comandante.creeper.merchant.bank.commands.DoneCommand;
-import com.comandante.creeper.merchant.lockers.*;
+import com.comandante.creeper.merchant.lockers.GetCommand;
+import com.comandante.creeper.merchant.lockers.LockerCommandRegistry;
+import com.comandante.creeper.merchant.lockers.PutCommand;
+import com.comandante.creeper.merchant.lockers.QueryCommand;
 import com.comandante.creeper.server.CreeperCommandRegistry;
 
 public class ConfigureCommands {
@@ -31,10 +33,8 @@ public class ConfigureCommands {
         lockerCommandRegistry.addCommand(new GetCommand(gameManager));
         lockerCommandRegistry.addCommand(new QueryCommand(gameManager));
         lockerCommandRegistry.addCommand(new com.comandante.creeper.merchant.lockers.DoneCommand(gameManager));
-
     }
 
-
     public static void configure(GameManager gameManager) {
         creeperCommandRegistry = new CreeperCommandRegistry(new UnknownCommand(gameManager));
         creeperCommandRegistry.addCommand(new DropCommand(gameManager));
@@ -88,5 +88,11 @@ public class ConfigureCommands {
         creeperCommandRegistry.addCommand(new SetCommand(gameManager));
         creeperCommandRegistry.addCommand(new DelCommand(gameManager));
         creeperCommandRegistry.addCommand(new OpCommand(gameManager));
+        creeperCommandRegistry.addCommand(new KillTallyCommand(gameManager));
+        creeperCommandRegistry.addCommand(new CompareCommand(gameManager));
+        creeperCommandRegistry.addCommand(new CardsCommand(gameManager));
+        creeperCommandRegistry.addCommand(new SpellsCommand(gameManager));
+        creeperCommandRegistry.addCommand(new LeaveCommand(gameManager));
+        creeperCommandRegistry.addCommand(new BackCommand(gameManager));
     }
 }
diff --git a/src/main/java/com/comandante/creeper/ConfigureNpc.java b/src/main/java/com/comandante/creeper/ConfigureNpc.java
old mode 100755
new mode 100644
index 52b4d0fae0985e37f94a975e84d5f4a9189cbef6..2907a39fadfd41b00c1e35f6a738cbc1fec17c2b
--- a/src/main/java/com/comandante/creeper/ConfigureNpc.java
+++ b/src/main/java/com/comandante/creeper/ConfigureNpc.java
@@ -4,7 +4,6 @@ import com.comandante.creeper.Items.*;
 import com.comandante.creeper.entity.EntityManager;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.merchant.*;
-import com.comandante.creeper.merchant.GrimulfWizard;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.npc.NpcExporter;
 import com.comandante.creeper.spawner.ItemSpawner;
@@ -16,14 +15,14 @@ import com.comandante.creeper.world.Area;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
-import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 public class ConfigureNpc {
 
-    public static void configureAllNpcs(GameManager gameManager) throws FileNotFoundException {
+    public static void configureAllNpcs(GameManager gameManager) throws IOException {
         EntityManager entityManager = gameManager.getEntityManager();
         List<Npc> npcsFromFile = NpcExporter.getNpcsFromFile(gameManager);
         for (Npc npc: npcsFromFile) {
@@ -36,127 +35,54 @@ public class ConfigureNpc {
         }
     }
 
-    public static void configure(EntityManager entityManager, GameManager gameManager) throws FileNotFoundException {
+    public static void configure(EntityManager entityManager, GameManager gameManager) throws IOException {
 
         configureAllNpcs(gameManager);
 
         Main.startUpMessage("Adding beer");
-        ItemSpawner itemSpawner = new ItemSpawner(ItemType.BEER, new SpawnRuleBuilder().setArea(Area.NEWBIE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(100).setMaxPerRoom(5).setRandomPercent(40).createSpawnRule(), gameManager);
-        ItemSpawner itemSpawner1 = new ItemSpawner(ItemType.BEER, new SpawnRuleBuilder().setArea(Area.FANCYHOUSE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(12).setMaxPerRoom(2).setRandomPercent(50).createSpawnRule(), gameManager);
-        ItemSpawner itemSpawner2 = new ItemSpawner(ItemType.BEER, new SpawnRuleBuilder().setArea(Area.HOUSE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(12).setMaxPerRoom(2).setRandomPercent(50).createSpawnRule(), gameManager);
-        ItemSpawner itemSpawner3 = new ItemSpawner(ItemType.PURPLE_DRANK, new SpawnRuleBuilder().setArea(Area.FANCYHOUSE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(30).setMaxPerRoom(5).setRandomPercent(50).createSpawnRule(), gameManager);
-        ItemSpawner itemSpawner4 = new ItemSpawner(ItemType.PURPLE_DRANK, new SpawnRuleBuilder().setArea(Area.HOUSE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(30).setMaxPerRoom(5).setRandomPercent(50).createSpawnRule(), gameManager);
-        ItemSpawner itemSpawner5 = new ItemSpawner(ItemType.KEY, new SpawnRuleBuilder().setArea(Area.LOBBY).setSpawnIntervalTicks(600).setMaxInstances(1).setMaxPerRoom(1).setRandomPercent(5).createSpawnRule(), gameManager);
+        ItemSpawner itemSpawner = new ItemSpawner(ItemType.SMALL_HEALTH_POTION, new SpawnRuleBuilder().setArea(Area.NEWBIE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(100).setMaxPerRoom(5).setRandomPercent(40).createSpawnRule(), gameManager);
+        ItemSpawner itemSpawner1 = new ItemSpawner(ItemType.SMALL_HEALTH_POTION, new SpawnRuleBuilder().setArea(Area.FANCYHOUSE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(12).setMaxPerRoom(2).setRandomPercent(50).createSpawnRule(), gameManager);
+        ItemSpawner itemSpawner2 = new ItemSpawner(ItemType.SMALL_HEALTH_POTION, new SpawnRuleBuilder().setArea(Area.HOUSE_ZONE).setSpawnIntervalTicks(600).setMaxInstances(12).setMaxPerRoom(2).setRandomPercent(50).createSpawnRule(), gameManager);
+         ItemSpawner itemSpawner5 = new ItemSpawner(ItemType.KEY, new SpawnRuleBuilder().setArea(Area.LOBBY).setSpawnIntervalTicks(600).setMaxInstances(1).setMaxPerRoom(1).setRandomPercent(5).createSpawnRule(), gameManager);
 
         entityManager.addEntity(itemSpawner);
         entityManager.addEntity(itemSpawner1);
         entityManager.addEntity(itemSpawner2);
-        entityManager.addEntity(itemSpawner3);
-        entityManager.addEntity(itemSpawner4);
         entityManager.addEntity(itemSpawner5);
 
         Map<Integer, MerchantItemForSale> itemsForSale = Maps.newLinkedHashMap();
-        itemsForSale.put(1, new MerchantItemForSale(ItemType.BEER, 8));
+        itemsForSale.put(1, new MerchantItemForSale(ItemType.SMALL_HEALTH_POTION, 8));
         itemsForSale.put(2, new MerchantItemForSale(ItemType.PURPLE_DRANK, 80));
-        itemsForSale.put(3, new MerchantItemForSale(ItemType.LEATHER_SATCHEL, 25000));
-        itemsForSale.put(4, new MerchantItemForSale(ItemType.BIGGERS_SKIN_SATCHEL, 250000));
-        itemsForSale.put(5, new MerchantItemForSale(ItemType.STRENGTH_ELIXIR, 2000));
-        itemsForSale.put(6, new MerchantItemForSale(ItemType.CHRONIC_JOOSE, 4000));
-        itemsForSale.put(7, new MerchantItemForSale(ItemType.GUCCI_PANTS, 80000000));
+        itemsForSale.put(3, new MerchantItemForSale(ItemType.BIGGERS_SKIN_SATCHEL, 25000));
 
         LloydBartender lloydBartender = new LloydBartender(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), itemsForSale);
         gameManager.getRoomManager().addMerchant(64, lloydBartender);
         
         Map<Integer, MerchantItemForSale> nigelForSale = Maps.newLinkedHashMap();
-        nigelForSale.put(1, new MerchantItemForSale(ItemType.BEER, 6));
+        nigelForSale.put(1, new MerchantItemForSale(ItemType.SMALL_HEALTH_POTION, 6));
         
         NigelBartender nigelBartender = new NigelBartender(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), nigelForSale);
         gameManager.getRoomManager().addMerchant(377, nigelBartender);
 
         Map<Integer, MerchantItemForSale> blacksmithItems = Maps.newHashMap();
-        blacksmithItems.put(1, new MerchantItemForSale(ItemType.BROAD_SWORD, 1000));
-        blacksmithItems.put(2, new MerchantItemForSale(ItemType.IRON_BOOTS, 800));
-        blacksmithItems.put(3, new MerchantItemForSale(ItemType.IRON_BRACERS, 400));
-        blacksmithItems.put(4, new MerchantItemForSale(ItemType.IRON_HELMET, 500));
-        blacksmithItems.put(5, new MerchantItemForSale(ItemType.IRON_CHEST_PLATE, 1500));
-        blacksmithItems.put(6, new MerchantItemForSale(ItemType.IRON_LEGGINGS, 1100));
-        blacksmithItems.put(7, new MerchantItemForSale(ItemType.PHANTOM_SWORD, 7000));
-        blacksmithItems.put(8, new MerchantItemForSale(ItemType.PHANTOM_HELMET, 3500));
-        blacksmithItems.put(9, new MerchantItemForSale(ItemType.PHANTOM_BOOTS, 3000));
-        blacksmithItems.put(10, new MerchantItemForSale(ItemType.PHANTOM_BRACERS, 1500));
-        blacksmithItems.put(11, new MerchantItemForSale(ItemType.PHANTOM_LEGGINGS, 4000));
-        blacksmithItems.put(12, new MerchantItemForSale(ItemType.MITHRIL_SWORD, 14000));
-        blacksmithItems.put(13, new MerchantItemForSale(ItemType.MITHRIL_HELMET, 7000));
-        blacksmithItems.put(14, new MerchantItemForSale(ItemType.MITHRIL_CHESTPLATE, 10000));
-        blacksmithItems.put(15, new MerchantItemForSale(ItemType.MITHRIL_BOOTS, 6000));
-        blacksmithItems.put(16, new MerchantItemForSale(ItemType.MITHRIL_BRACERS, 4000));
-        blacksmithItems.put(17, new MerchantItemForSale(ItemType.MITHRIL_LEGGINGS, 8000));
-        blacksmithItems.put(18, new MerchantItemForSale(ItemType.PYAMITE_SWORD, 20000));
-        blacksmithItems.put(19, new MerchantItemForSale(ItemType.PYAMITE_HELMET, 14000));
-        blacksmithItems.put(20, new MerchantItemForSale(ItemType.PYAMITE_CHESTPLATE, 20000));
-        blacksmithItems.put(21, new MerchantItemForSale(ItemType.PYAMITE_BOOTS, 12000));
-        blacksmithItems.put(22, new MerchantItemForSale(ItemType.PYAMITE_BRACERS, 8000));
-        blacksmithItems.put(23, new MerchantItemForSale(ItemType.PYAMITE_LEGGINGS, 16000));
-        blacksmithItems.put(24, new MerchantItemForSale(ItemType.VULCERIUM_SWORD, 160000));
-        blacksmithItems.put(25, new MerchantItemForSale(ItemType.VULCERIUM_HELMET, 37000));
-        blacksmithItems.put(26, new MerchantItemForSale(ItemType.VULCERIUM_CHESTPLATE, 52000));
-        blacksmithItems.put(27, new MerchantItemForSale(ItemType.VULCERIUM_BOOTS, 38000));
-        blacksmithItems.put(28, new MerchantItemForSale(ItemType.VULCERIUM_BRACERS, 29000));
-        blacksmithItems.put(29, new MerchantItemForSale(ItemType.VULCERIUM_LEGGINGS, 52000));
-        blacksmithItems.put(30, new MerchantItemForSale(ItemType.BISMUTH_SWORD, 3000000));
-        blacksmithItems.put(31, new MerchantItemForSale(ItemType.BISMUTH_HELMET, 2400000));
-        blacksmithItems.put(32, new MerchantItemForSale(ItemType.LEATHER_SATCHEL, 25000));
+        blacksmithItems.put(1, new MerchantItemForSale(ItemType.BERSERKER_BATON, 1000));
+        blacksmithItems.put(2, new MerchantItemForSale(ItemType.BERSEKER_BOOTS, 350));
+        blacksmithItems.put(3, new MerchantItemForSale(ItemType.BERSERKER_BRACERS, 350));
+        blacksmithItems.put(4, new MerchantItemForSale(ItemType.BERSEKER_HELM, 350));
+        blacksmithItems.put(5, new MerchantItemForSale(ItemType.BERSERKER_CHEST, 700));
+        blacksmithItems.put(6, new MerchantItemForSale(ItemType.BERSEKER_SHORTS, 850));
+        blacksmithItems.put(7, new MerchantItemForSale(ItemType.LEATHER_SATCHEL, 600));
 
-        Map<Integer, MerchantItemForSale> grimulfItems = Maps.newHashMap();        
-        grimulfItems.put(1, new MerchantItemForSale(ItemType.MARIJUANA, 100));
-        grimulfItems.put(2, new MerchantItemForSale(ItemType.TAPPERHET_SWORD, 60000));
-        grimulfItems.put(3, new MerchantItemForSale(ItemType.BIGGERS_SKIN_SATCHEL, 250000));
-        grimulfItems.put(4, new MerchantItemForSale(ItemType.DWARF_BOOTS_OF_AGILITY, 10000));
-       // grimulfItems.put(5, new MerchantItemForSale(ItemType.GOLDEN_WAND, 4000000000));
-        grimulfItems.put(5, new MerchantItemForSale(ItemType.MITHAEM_LEAF, 1400000000));
-
-        Map<Integer, MerchantItemForSale> ketilItems = Maps.newHashMap();          
-        ketilItems.put(1, new MerchantItemForSale(ItemType.BEER, 12));
-        ketilItems.put(2, new MerchantItemForSale(ItemType.PURPLE_DRANK, 120));
-        ketilItems.put(3, new MerchantItemForSale(ItemType.MARIJUANA, 100));
-        ketilItems.put(4, new MerchantItemForSale(ItemType.PYAMITE_ICEAXE, 10000000));
-        ketilItems.put(5, new MerchantItemForSale(ItemType.STRENGTH_ELIXIR, 3000));
-        ketilItems.put(6, new MerchantItemForSale(ItemType.CHRONIC_JOOSE, 5500));
-        ketilItems.put(7, new MerchantItemForSale(ItemType.VIAGRA_SWORD, 900000000));
-        
-        Map<Integer, MerchantItemForSale> blackbeardItems = Maps.newHashMap();          
-        blackbeardItems.put(1, new MerchantItemForSale(ItemType.IRON_LOCKPICKING_SET, 8000000));
-        blackbeardItems.put(2, new MerchantItemForSale(ItemType.PYAMITE_LOCKPICKING_SET, 8000000));
-        blackbeardItems.put(3, new MerchantItemForSale(ItemType.SPOOL_OF_CLIMBING_ROPE, 8000000));
-        blackbeardItems.put(4, new MerchantItemForSale(ItemType.BLACK_CLOAK, 8000000));
-        blackbeardItems.put(5, new MerchantItemForSale(ItemType.SMELTING_CRUCIBLE, 8000000));
-        blackbeardItems.put(6, new MerchantItemForSale(ItemType.LEATHER_SHOES, 8000000));
-        
-        Map<Integer, MerchantItemForSale> wentworthItems = Maps.newHashMap();          
-        wentworthItems.put(1, new MerchantItemForSale(ItemType.GENTLEMANS_TOP_HAT, 8000000));
-        wentworthItems.put(2, new MerchantItemForSale(ItemType.LEATHER_GLOVES, 8000000));
-        wentworthItems.put(3, new MerchantItemForSale(ItemType.WOOL_SCARF, 8000000));
-        wentworthItems.put(4, new MerchantItemForSale(ItemType.LEATHER_BELT, 8000000));
-        wentworthItems.put(5, new MerchantItemForSale(ItemType.SILK_SASH, 8000000));
-        wentworthItems.put(6, new MerchantItemForSale(ItemType.LEATHER_SCABBARD, 8000000));
-        wentworthItems.put(7, new MerchantItemForSale(ItemType.BYSENSKIN_SCABBARD, 19000000));
-        wentworthItems.put(8, new MerchantItemForSale(ItemType.IRON_SPECTACLES, 8000000));
-        wentworthItems.put(9, new MerchantItemForSale(ItemType.GOLDEN_SPECTACLES, 40000000));
-        wentworthItems.put(10, new MerchantItemForSale(ItemType.NOBLEMANS_SHOULDER_CLASP, 200000000));
-        wentworthItems.put(11, new MerchantItemForSale(ItemType.WOODSMANS_TUNIC, 8000000));
-        wentworthItems.put(12, new MerchantItemForSale(ItemType.PLAIN_WHITE_ROBE, 8000000));
-        wentworthItems.put(13, new MerchantItemForSale(ItemType.FINE_POWDERED_WIG, 30000000));
-        wentworthItems.put(14, new MerchantItemForSale(ItemType.HABROK_FEATHER_HAT, 10000000));
-        wentworthItems.put(15, new MerchantItemForSale(ItemType.POLISHED_IRON_CODPIECE, 30000000));
-        wentworthItems.put(16, new MerchantItemForSale(ItemType.GOLDEN_CODPIECE, 950000000));
-
-        BlackbeardRogue rogueshop = new BlackbeardRogue(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), blackbeardItems);
-        gameManager.getRoomManager().addMerchant(864, rogueshop);
-        
         Blacksmith blacksmith = new Blacksmith(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), blacksmithItems);
         gameManager.getRoomManager().addMerchant(66, blacksmith);
         gameManager.getRoomManager().addMerchant(253, blacksmith);
 
+        Map<Integer, MerchantItemForSale> wizarditems = Maps.newHashMap();
+        wizarditems.put(1, new MerchantItemForSale(ItemType.LIGHTNING_SPELLBOOKNG, 5000));
+
+        Wizard wizard = new Wizard(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), wizarditems);
+        gameManager.getRoomManager().addMerchant(98, wizard);
+
         JimBanker jimBanker = new JimBanker(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), null);
         gameManager.getRoomManager().addMerchant(65, jimBanker);
         gameManager.getRoomManager().addMerchant(209, jimBanker);
@@ -164,15 +90,6 @@ public class ConfigureNpc {
         LockerRoomGuy lockerRoomGuy = new LockerRoomGuy(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), null);
         gameManager.getRoomManager().addMerchant(63, lockerRoomGuy);
 
-        GrimulfWizard grimulfWizard = new GrimulfWizard(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), grimulfItems);
-        gameManager.getRoomManager().addMerchant(102, grimulfWizard);
-        
-        WentworthTailor wentworthTailor = new WentworthTailor(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), wentworthItems);
-        gameManager.getRoomManager().addMerchant(865, wentworthTailor);
-        
-        KetilCommissary ketilCommissary = new KetilCommissary(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), ketilItems);
-        gameManager.getRoomManager().addMerchant(420, ketilCommissary);
-
         ForageBuilder marijuanaForageBuilder = new ForageBuilder();
         marijuanaForageBuilder.setItemType(ItemType.MARIJUANA);
         marijuanaForageBuilder.setMinAmt(1);
@@ -185,267 +102,6 @@ public class ConfigureNpc {
         gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE2_ZONE, marijuanaForageBuilder);
         gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE1_ZONE, marijuanaForageBuilder);
 
-        ForageBuilder hazeForageBuilder = new ForageBuilder();
-        hazeForageBuilder.setItemType(ItemType.HAZE);
-        hazeForageBuilder.setMinAmt(1);
-        hazeForageBuilder.setMaxAmt(3);
-        hazeForageBuilder.setPctOfSuccess(5);
-        hazeForageBuilder.setForageExperience(10);
-        hazeForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE8_ZONE, hazeForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE9_ZONE, hazeForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE10_ZONE, hazeForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH12_ZONE, hazeForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH2_ZONE, hazeForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH3_ZONE, hazeForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH4_ZONE, hazeForageBuilder);
-
-        ForageBuilder aexirianForageBuilder = new ForageBuilder();
-        aexirianForageBuilder.setItemType(ItemType.AEXIRIAN_ROOT);
-        aexirianForageBuilder.setMinAmt(1);
-        aexirianForageBuilder.setMaxAmt(3);
-        aexirianForageBuilder.setPctOfSuccess(5);
-        aexirianForageBuilder.setForageExperience(10);
-        aexirianForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, aexirianForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, aexirianForageBuilder);
-
-        ForageBuilder mithaemForageBuilder = new ForageBuilder();
-        mithaemForageBuilder.setItemType(ItemType.MITHAEM_LEAF);
-        mithaemForageBuilder.setMinAmt(1);
-        mithaemForageBuilder.setMaxAmt(3);
-        mithaemForageBuilder.setPctOfSuccess(5);
-        mithaemForageBuilder.setForageExperience(10);
-        mithaemForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.TISLAND3_ZONE, mithaemForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.TISLAND4_ZONE, mithaemForageBuilder);
-
-        ForageBuilder duriccaForageBuilder = new ForageBuilder();
-        duriccaForageBuilder.setItemType(ItemType.DURICCA_ROOT);
-        duriccaForageBuilder.setMinAmt(1);
-        duriccaForageBuilder.setMaxAmt(3);
-        duriccaForageBuilder.setPctOfSuccess(5);
-        duriccaForageBuilder.setForageExperience(10);
-        duriccaForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.TOFT1_ZONE, duriccaForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.TOFT2_ZONE, duriccaForageBuilder);
-
-        ForageBuilder pondeselForageBuilder = new ForageBuilder();
-        pondeselForageBuilder.setItemType(ItemType.PONDESEL_BERRY);
-        pondeselForageBuilder.setMinAmt(1);
-        pondeselForageBuilder.setMaxAmt(3);
-        pondeselForageBuilder.setPctOfSuccess(5);
-        pondeselForageBuilder.setForageExperience(10);
-        pondeselForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.TISLAND6_ZONE, pondeselForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.TISLAND7_ZONE, pondeselForageBuilder);
-
-        ForageBuilder vikalionusForageBuilder = new ForageBuilder();
-        vikalionusForageBuilder.setItemType(ItemType.VIKALIONUS_CAP);
-        vikalionusForageBuilder.setMinAmt(1);
-        vikalionusForageBuilder.setMaxAmt(3);
-        vikalionusForageBuilder.setPctOfSuccess(5);
-        vikalionusForageBuilder.setForageExperience(10);
-        vikalionusForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.NORTH12_ZONE, vikalionusForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH13_ZONE, vikalionusForageBuilder);
-
-        ForageBuilder loornsForageBuilder = new ForageBuilder();
-        loornsForageBuilder.setItemType(ItemType.LOORNS_LACE);
-        loornsForageBuilder.setMinAmt(1);
-        loornsForageBuilder.setMaxAmt(3);
-        loornsForageBuilder.setPctOfSuccess(5);
-        loornsForageBuilder.setForageExperience(10);
-        loornsForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE4_ZONE, loornsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE5_ZONE, loornsForageBuilder);
-
-        ForageBuilder tournearesForageBuilder = new ForageBuilder();
-        tournearesForageBuilder.setItemType(ItemType.TOURNEARES_LEAF);
-        tournearesForageBuilder.setMinAmt(1);
-        tournearesForageBuilder.setMaxAmt(3);
-        tournearesForageBuilder.setPctOfSuccess(5);
-        tournearesForageBuilder.setForageExperience(10);
-        tournearesForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, tournearesForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, tournearesForageBuilder);
-
-        ForageBuilder haussianForageBuilder = new ForageBuilder();
-        haussianForageBuilder.setItemType(ItemType.HAUSSIAN_BERRY);
-        haussianForageBuilder.setMinAmt(1);
-        haussianForageBuilder.setMaxAmt(3);
-        haussianForageBuilder.setPctOfSuccess(5);
-        haussianForageBuilder.setForageExperience(10);
-        haussianForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, haussianForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, haussianForageBuilder);
-
-        ForageBuilder pertilliumForageBuilder = new ForageBuilder();
-        pertilliumForageBuilder.setItemType(ItemType.PERTILLIUM_ROOT);
-        pertilliumForageBuilder.setMinAmt(1);
-        pertilliumForageBuilder.setMaxAmt(3);
-        pertilliumForageBuilder.setPctOfSuccess(5);
-        pertilliumForageBuilder.setForageExperience(10);
-        pertilliumForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, pertilliumForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, pertilliumForageBuilder);
-
-        ForageBuilder hycianthisForageBuilder = new ForageBuilder();
-        hycianthisForageBuilder.setItemType(ItemType.HYCIANTHIS_BARK);
-        hycianthisForageBuilder.setMinAmt(1);
-        hycianthisForageBuilder.setMaxAmt(3);
-        hycianthisForageBuilder.setPctOfSuccess(5);
-        hycianthisForageBuilder.setForageExperience(10);
-        hycianthisForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, hycianthisForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, hycianthisForageBuilder);
-
-        ForageBuilder punilareForageBuilder = new ForageBuilder();
-        punilareForageBuilder.setItemType(ItemType.PUNILARE_FERN);
-        punilareForageBuilder.setMinAmt(1);
-        punilareForageBuilder.setMaxAmt(3);
-        punilareForageBuilder.setPctOfSuccess(5);
-        punilareForageBuilder.setForageExperience(10);
-        punilareForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, punilareForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, punilareForageBuilder);
-
-        ForageBuilder keakiarForageBuilder = new ForageBuilder();
-        keakiarForageBuilder.setItemType(ItemType.KEAKIAR_CAP);
-        keakiarForageBuilder.setMinAmt(1);
-        keakiarForageBuilder.setMaxAmt(3);
-        keakiarForageBuilder.setPctOfSuccess(5);
-        keakiarForageBuilder.setForageExperience(10);
-        keakiarForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, keakiarForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, keakiarForageBuilder);
-
-        ForageBuilder dirtyBombForageBuilder = new ForageBuilder();
-        dirtyBombForageBuilder.setItemType(ItemType.DIRTY_BOMB);
-        dirtyBombForageBuilder.setMinAmt(1);
-        dirtyBombForageBuilder.setMaxAmt(3);
-        dirtyBombForageBuilder.setPctOfSuccess(2);
-        dirtyBombForageBuilder.setForageExperience(100);
-        dirtyBombForageBuilder.setCoolDownTicks(600);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, dirtyBombForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, dirtyBombForageBuilder);
-
-        ForageBuilder radsuitHelmetForageBuilder = new ForageBuilder();
-        radsuitHelmetForageBuilder.setItemType(ItemType.RADSUIT_HELMET);
-        radsuitHelmetForageBuilder.setMinAmt(1);
-        radsuitHelmetForageBuilder.setMaxAmt(1);
-        radsuitHelmetForageBuilder.setPctOfSuccess(.5);
-        radsuitHelmetForageBuilder.setForageExperience(500);
-        radsuitHelmetForageBuilder.setCoolDownTicks(1000);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, radsuitHelmetForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, radsuitHelmetForageBuilder);
-
-        ForageBuilder radsuitChestplateForageBuilder = new ForageBuilder();
-        radsuitChestplateForageBuilder.setItemType(ItemType.RADSUIT_CHESTPLATE);
-        radsuitChestplateForageBuilder.setMinAmt(1);
-        radsuitChestplateForageBuilder.setMaxAmt(1);
-        radsuitChestplateForageBuilder.setPctOfSuccess(.5);
-        radsuitChestplateForageBuilder.setForageExperience(500);
-        radsuitChestplateForageBuilder.setCoolDownTicks(1000);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, radsuitChestplateForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, radsuitChestplateForageBuilder);
-
-        ForageBuilder radsuitBracersForageBuilder = new ForageBuilder();
-        radsuitBracersForageBuilder.setItemType(ItemType.RADSUIT_BRACERS);
-        radsuitBracersForageBuilder.setMinAmt(1);
-        radsuitBracersForageBuilder.setMaxAmt(1);
-        radsuitBracersForageBuilder.setPctOfSuccess(.5);
-        radsuitBracersForageBuilder.setForageExperience(500);
-        radsuitBracersForageBuilder.setCoolDownTicks(1000);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, radsuitBracersForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, radsuitBracersForageBuilder);
-
-        ForageBuilder radsuitLeggingsForageBuilder = new ForageBuilder();
-        radsuitLeggingsForageBuilder.setItemType(ItemType.RADSUIT_LEGGINGS);
-        radsuitLeggingsForageBuilder.setMinAmt(1);
-        radsuitLeggingsForageBuilder.setMaxAmt(1);
-        radsuitLeggingsForageBuilder.setPctOfSuccess(.5);
-        radsuitLeggingsForageBuilder.setForageExperience(500);
-        radsuitLeggingsForageBuilder.setCoolDownTicks(1000);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, radsuitLeggingsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, radsuitLeggingsForageBuilder);
-
-        ForageBuilder radsuitBootsForageBuilder = new ForageBuilder();
-        radsuitBootsForageBuilder.setItemType(ItemType.RADSUIT_BOOTS);
-        radsuitBootsForageBuilder.setMinAmt(1);
-        radsuitBootsForageBuilder.setMaxAmt(1);
-        radsuitBootsForageBuilder.setPctOfSuccess(.5);
-        radsuitBootsForageBuilder.setForageExperience(500);
-        radsuitBootsForageBuilder.setCoolDownTicks(1000);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE15_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH14_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.SOUTH1_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE14_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH10_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.NORTH11_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN4_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN5_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN2_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.WESTERN3_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE6_ZONE, radsuitBootsForageBuilder);
-        gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE7_ZONE, radsuitBootsForageBuilder);
-
-        SpellRegistry.addSpell(new LightningSpell(gameManager));
-        SpellRegistry.addSpell(new FreezeSpell(gameManager));
-        SpellRegistry.addSpell(new ClumsinessSpell(gameManager));
-        SpellRegistry.addSpell(new RestoreSpell(gameManager));
-        SpellRegistry.addSpell(new HealingSpell(gameManager));
-        SpellRegistry.addSpell(new LizardlySpell(gameManager));
-        SpellRegistry.addSpell(new BlackHoleSpell(gameManager));
+        SpellTriggerRegistry.addSpell(new LightningSpell(gameManager));
     }
 }
diff --git a/src/main/java/com/comandante/creeper/CreeperConfiguration.java b/src/main/java/com/comandante/creeper/CreeperConfiguration.java
index 79729b0c4355c4d104c83a69b6f1d5e71b7285de..ca65d90f87c9fe9ef25dce43045a4af15a13cea7 100644
--- a/src/main/java/com/comandante/creeper/CreeperConfiguration.java
+++ b/src/main/java/com/comandante/creeper/CreeperConfiguration.java
@@ -66,7 +66,7 @@ public class CreeperConfiguration {
     public final String weatherUndergroundApiKey;
 
     public static final String MAX_GOSSIP_CACHE_SIZE = "max.gossip.cache.size";
-    public static final int MAX_GOSSIP_CACHE_SIZE_DEFAULT = 100;
+    public static final int MAX_GOSSIP_CACHE_SIZE_DEFAULT = 1000;
     public final int maxGossipCacheSize;
 
     public CreeperConfiguration(Configuration configuration) {
diff --git a/src/main/java/com/comandante/creeper/CreeperEvent.java b/src/main/java/com/comandante/creeper/CreeperEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..a50a8fdc46b680d35710ec9e13973dff2cb122d5
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/CreeperEvent.java
@@ -0,0 +1,5 @@
+package com.comandante.creeper;
+
+public interface CreeperEvent {
+    void run();
+}
diff --git a/src/main/java/com/comandante/creeper/CreeperUtils.java b/src/main/java/com/comandante/creeper/CreeperUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..00ecb36948582eeced355e164a01034666e5a2f4
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/CreeperUtils.java
@@ -0,0 +1,102 @@
+package com.comandante.creeper;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class CreeperUtils {
+    /*  Prints things "next" to each other, like this:
+   ┌─────────┐   ┌─────────┐   ┌─────────┐   ┌─────────┐
+   │4        │   │2        │   │5        │   │5        │
+   │         │   │         │   │         │   │         │
+   │         │   │         │   │         │   │         │
+   │   ♦     │   │   ♠     │   │   ♣     │   │   ♦     │
+   │         │   │         │   │         │   │         │
+   │         │   │         │   │         │   │         │
+   │       4 │   │       2 │   │       5 │   │       5 │
+   └─────────┘   └─────────┘   └─────────┘   └─────────┘
+   */
+    public static String printStringsNextToEachOther(List<String> strings, String seperator) {
+        // Find the "longest", meaning most newlines string.
+        final String[] maxHeightLine = {strings.get(0)};
+        strings.forEach(s -> {
+            int height = s.split("[\\r\\n]+").length;
+            if (maxHeightLine[0] != null && height > maxHeightLine[0].split("[\\r\\n]+").length) {
+                maxHeightLine[0] = s;
+            }
+        });
+
+        final int[] maxLineLength = {0};
+        // Split all of the strings, to create a List of a List Of Strings
+        // Make them all even length.  This is terrible streams api usage.
+        List<List<String>> textToJoin = strings.stream()
+                .map((Function<String, List<String>>) s -> Lists.newArrayList(s.split("[\\r\\n]+"))).map(strings1 -> {
+                    String asciiColorPattern = "\u001B\\[[;\\d]*m";
+                    strings1.forEach(s -> {
+                        if (s.replaceAll(asciiColorPattern, "").length() > maxLineLength[0]) {
+                            maxLineLength[0] = s.replaceAll(asciiColorPattern, "").length();
+                        }
+                    });
+                    List<String> newStrings = Lists.newArrayList();
+                    strings1.forEach(s -> {
+                        String cleaned = s.replaceAll(asciiColorPattern, "");
+                        int diff = maxLineLength[0] - cleaned.length();
+                        for (int i = 0; i < diff; i++) {
+                            s += " ";
+                        }
+                        newStrings.add(s);
+                    });
+                    return newStrings;
+                })
+                .collect(Collectors.toList());
+
+
+        // Go through and piece together the lines, by removing the top of each list and concatenating it
+        final StringBuilder[] sb = {new StringBuilder()};
+        List<String> splitLines = Lists.newArrayList(maxHeightLine[0].split("[\\r\\n]+"));
+        splitLines
+                .forEach(new Consumer<String>() {
+                    @Override
+                    public void accept(String s) {
+                        textToJoin.forEach(ss -> {
+                            if (ss.size() > 0) {
+                                sb[0].append(ss.remove(0)).append(seperator);
+                            } else {
+                                sb[0].append(seperator);
+                            }
+                        });
+                        sb[0].append("\r\n");
+                        String finalformatted = sb[0].toString();
+                        sb[0] = new StringBuilder(replaceLast(finalformatted, seperator + "\r\n", "\r\n"));
+                    }
+                });
+        return sb[0].toString();
+    }
+
+    public static String replaceLast(String string, String toReplace, String replacement) {
+        int pos = string.lastIndexOf(toReplace);
+        if (pos > -1) {
+            return string.substring(0, pos)
+                    + replacement
+                    + string.substring(pos + toReplace.length(), string.length());
+        } else {
+            return string;
+        }
+    }
+
+    public static String trimTrailingBlanks( String str)
+    {
+        if( str == null)
+            return null;
+        int len = str.length();
+        for( ; len > 0; len--)
+        {
+            if( ! Character.isWhitespace( str.charAt( len - 1)))
+                break;
+        }
+        return str.substring( 0, len);
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/IrcBotService.java b/src/main/java/com/comandante/creeper/IrcBotService.java
index dcfd448aa86bece066e1b3f921514dcdfacdfdeb..0fbea14678c8340835a7340a0e49bdfa93f97482 100644
--- a/src/main/java/com/comandante/creeper/IrcBotService.java
+++ b/src/main/java/com/comandante/creeper/IrcBotService.java
@@ -34,6 +34,7 @@ public class IrcBotService extends AbstractIdleService {
                 .addAutoJoinChannel(creeperConfiguration.ircChannel)
                 .addListener(new MyListener(gameManager, 376))
                 .setVersion("Creeper MUD IRC But.")
+                .setAutoReconnect(true)
                 .buildConfiguration();
         bot = new PircBotX(configuration);
         // bot.startBot();
diff --git a/src/main/java/com/comandante/creeper/Items/ItemType.java b/src/main/java/com/comandante/creeper/Items/ItemType.java
old mode 100755
new mode 100644
index a7bc0ff7bf3ebbf2ff1020aa50b1a4b8b38dca31..1a5bb8b0fb87dc8891ed0ad7cacecefd1b3d7e22
--- a/src/main/java/com/comandante/creeper/Items/ItemType.java
+++ b/src/main/java/com/comandante/creeper/Items/ItemType.java
@@ -26,32 +26,21 @@ public enum ItemType {
             Rarity.BASIC,
             10, Sets.<TimeTracker.TimeOfDay>newHashSet(TimeTracker.TimeOfDay.NIGHT)),
 
-    BEER(2, Arrays.asList("beer", "can of beer", "b"),
-            "a dented can of " + CYAN + "beer" + RESET,
-            "a " + CYAN + "beer" + RESET + " lies on the ground, unopened",
-            "an ice cold " + CYAN + "beer" + RESET + " that restores 50 health" + RESET,
+    SMALL_HEALTH_POTION(2, Arrays.asList("potion", "health potion", "vial", "small vial of health potion", "p"),
+            "a small vial of " + RED + "health potion" + RESET,
+            "a small vial of " + RED + "health potion" + RESET + " rests on the ground.",
+            "a small vial of " + RED + "health potion" + RESET + " that restores 50 health" + RESET,
             true,
             0,
             60,
             false,
-            Rarity.BASIC,
-            1, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BOOK(3, Arrays.asList("book", "used book"),
-            MAGENTA + "a leather book" + RESET,
-            MAGENTA + "a well used book" + RESET + " with what looks like a leather back rests here.",
-            "A book written in a foreign language. Doesn't matter as you can't read.",
-            false,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
+            Rarity.OFTEN,
             1, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    BROAD_SWORD(4, Arrays.asList("sword", "broad", "a broad sword", "the broad sword"),
-            Color.CYAN + "the broad sword" + Color.RESET,
-            "an iron broad sword rests upon the ground.",
-            "an iron broad sword",
+    BERSERKER_BATON(3, Arrays.asList("baton", "a berserker baton", "b"),
+            Color.CYAN + "a berserker baton" + Color.RESET,
+            "a berserker baton rests upon the ground.",
+            "a berserker baton",
             false,
             0,
             60,
@@ -59,10 +48,10 @@ public enum ItemType {
             Rarity.BASIC,
             100, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    IRON_BOOTS(5, Arrays.asList("boots", "boot", "iron boots"),
-            Color.CYAN + "iron boots" + Color.RESET,
-            "a pair of iron boots are here on the ground.",
-            "a pair of iron boots",
+    BERSEKER_BOOTS(4, Arrays.asList("boots", "boot", "berserker boots", "b"),
+            Color.CYAN + "berserker boots" + Color.RESET,
+            "a pair of berserker boots are here on the ground.",
+            "a pair of berserker boots",
             false,
             0,
             60,
@@ -70,10 +59,10 @@ public enum ItemType {
             Rarity.BASIC,
             50, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    IRON_CHEST_PLATE(6, Arrays.asList("chest", "iron chest plate", "plate"),
-            "iron chest plate",
-            "an iron ches tplate is on the ground.",
-            "an iron chest plate",
+    BERSERKER_CHEST(5, Arrays.asList("chest", "berserker chest", "c"),
+            Color.CYAN + "berserker chest" + Color.RESET,
+            "a berserker chest is on the ground.",
+            "a berserker chest",
             false,
             0,
             60,
@@ -81,10 +70,10 @@ public enum ItemType {
             Rarity.BASIC,
             70, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    IRON_LEGGINGS(7, Arrays.asList("leggings", "iron leggings"),
-            "iron leggings",
-            "an a pair of iron leggings are here on the ground.",
-            "an iron pair of leggings",
+    BERSEKER_SHORTS(6, Arrays.asList("shorts", "berserker shorts", "s"),
+            Color.CYAN + "berserker shorts" + Color.RESET,
+            "a pair of berserker shorts are here on the ground.",
+            "a pair of berserker shorts",
             false,
             0,
             60,
@@ -92,21 +81,10 @@ public enum ItemType {
             Rarity.BASIC,
             80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    PHANTOM_SWORD(8, Arrays.asList("phantom", "phantom sword", "the phantom sword"),
-            Color.YELLOW + "the " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            500, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    IRON_BRACERS(9, Arrays.asList("bracers", "iron bracers"),
-            "iron bracers",
-            "an a pair of iron bracers are here on the ground.",
-            "an iron pair of bracers",
+    BERSERKER_BRACERS(7, Arrays.asList("bracers", "berserker bracers", "b"),
+            Color.CYAN + "berserker bracers" + Color.RESET,
+            "a pair of berserker bracers are here on the ground.",
+            "a pair of berserker bracers",
             false,
             0,
             60,
@@ -114,205 +92,18 @@ public enum ItemType {
             Rarity.BASIC,
             40, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    PHANTOM_HELMET(10, Arrays.asList("helmet", "phantom helmet", "the phantom helmet"),
-            Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            "a " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            250, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PHANTOM_CHESTPLATE(11, Arrays.asList("chestplate", "chest", "phantom chest plate", "the phantom chest plate"),
-            Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " chest plate" + Color.RESET,
-            "a " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " chest plate" + Color.RESET + " is on the ground.",
-            "a " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " chest plate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            350, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PHANTOM_BOOTS(12, Arrays.asList("boots", "phantom boots", "the phantom boots"),
-            Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            "a pair of " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            280, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PHANTOM_BRACERS(13, Arrays.asList("boots", "phantom bracers", "the phantom bracers"),
-            Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            250, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PHANTOM_LEGGINGS(14, Arrays.asList("leggings", "phantom leggings", "the phantom leggings"),
-            Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.CYAN + "phantom" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            290, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    IRON_HELMET(15, Arrays.asList("helmet", "iron helmet"),
-            "iron helmet",
-            "an iron helmet is on the ground.",
-            "an iron helmet",
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHRIL_SWORD(16, Arrays.asList("sword", "mithril sword", "mithril sword"),
-            Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            500, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHRIL_CHESTPLATE(17, Arrays.asList("chestplate", "a mithril chestplate", "mithril chestplate"),
-            Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            "a " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET + " is on the ground.",
-            "a " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            400, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHRIL_HELMET(18, Arrays.asList("helmet", "a mithril helmet", "mithril helmet"),
-            Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            "a " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            280, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHRIL_BRACERS(19, Arrays.asList("helmet", "mithril bracers", "mithril bracers"),
-            Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            300, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHRIL_LEGGINGS(20, Arrays.asList("helmet", "mithril leggings", "mithril leggings"),
-            Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            "a pair of " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            350, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHRIL_BOOTS(21, Arrays.asList("helmet", "mithril boots"),
-            Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            "a pair of " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.MAGENTA + "mithril" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            190, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PYAMITE_SWORD(22, Arrays.asList("sword", "pyamite sword", "pyamite sword"),
-            Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            3000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PYAMITE_CHESTPLATE(23, Arrays.asList("chestplate", "a pyamite chestplate", "pyamite chestplate"),
-            Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            "a " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET + " is on the ground.",
-            "a " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            2700, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PYAMITE_HELMET(24, Arrays.asList("helmet", "a pyamite helmet", "pyamite helmet"),
-            Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            "a " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            2000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PYAMITE_BRACERS(25, Arrays.asList("bracers", "pyamite bracers", "pyamite bracers"),
-            Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            2100, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PYAMITE_LEGGINGS(26, Arrays.asList("leggings", "pyamite leggings", "pyamite leggings"),
-            Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            "a pair of " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
+    BERSEKER_HELM(8, Arrays.asList("helm", "berserker helm", "h"),
+            Color.CYAN + "berserker helm" + Color.RESET,
+            "a berserker helm is on the ground.",
+            "a berserker helm",
             false,
             0,
             60,
             true,
             Rarity.BASIC,
-            2900, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PYAMITE_BOOTS(27, Arrays.asList("helmet", "pyamite boots"),
-            Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            "a pair of " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.GREEN + "pyamite" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            2000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
+            40, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    MARIJUANA(28, Arrays.asList("marijuana", "weed", "m", "w", "f", "flowers"),
+    MARIJUANA(9, Arrays.asList("marijuana", "weed", "m", "w", "f", "flowers"),
             Color.GREEN + "marijuana" + Color.RESET + " flowers" + Color.RESET,
             "some " + Color.GREEN + "marijuana" + Color.RESET + " flowers" + Color.RESET + " are here on the ground.",
             "some " + Color.GREEN + "marijuana" + Color.RESET + " flowers" + Color.RESET,
@@ -323,151 +114,7 @@ public enum ItemType {
             Rarity.BASIC,
             80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    TAPPERHET_SWORD(29, Arrays.asList("sword", "tapperhet sword"),
-            Color.BOLD_ON + Color.GREEN + "tapperhet" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "tapperhet" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "tapperhet" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            7000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_SWORD(30, Arrays.asList("sword", "vulcerium sword", "vulcerium sword"),
-            Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            10000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_CHESTPLATE(31, Arrays.asList("chestplate", "a vulcerium chestplate", "vulcerium chestplate"),
-            Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET + " is on the ground.",
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            9000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_HELMET(32, Arrays.asList("helmet", "a vulcerium helmet", "vulcerium helmet"),
-            Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            6000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_BRACERS(33, Arrays.asList("bracers", "vulcerium bracers", "vulcerium bracers"),
-            Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            5900, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_LEGGINGS(34, Arrays.asList("leggings", "vulcerium leggings", "vulcerium leggings"),
-            Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            "a pair of " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            7500, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_BOOTS(35, Arrays.asList("boots", "vulcerium boots"),
-            Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            "a pair of " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.RED + "vulcerium" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            7100, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    DWARF_BOOTS_OF_AGILITY(36, Arrays.asList("dwarf boots", "boots"),
-            Color.BLUE + "dwarf" + Color.RESET + Color.RED + " boots" + Color.RESET,
-            "a pair of " + Color.BLUE + "dwarf" + Color.RESET + Color.RED + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BLUE + "dwarf" + Color.RESET + Color.RED + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.UNCOMMON,
-            2500, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    DEATHCRAWLER_SCALES(37, Arrays.asList("deathcrawler scales", "scales"),
-            Color.BOLD_ON + Color.MAGENTA + "deathcrawler" + Color.RESET + Color.RED + " scales" + Color.RESET,
-            "some " + Color.BOLD_ON + Color.MAGENTA + "deathcrawler" + Color.RESET + Color.RED + " scales" + Color.RESET + " are on the ground.",
-            "some " + Color.BOLD_ON + Color.MAGENTA + "deathcrawler" + Color.RESET + Color.RED + " scales" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            700, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-
-    DWARVEN_PENDANT(38, Arrays.asList("dwarven pendant", "pendant"),
-            Color.BOLD_ON + Color.MAGENTA + "dwarven" + Color.RESET + Color.RED + " pendant" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "dwarven" + Color.RESET + Color.RED + " pendant" + Color.RESET + " are on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "dwarven" + Color.RESET + Color.RED + " pendant" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            450, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BYSEN_BALLS(39, Arrays.asList("bysen balls", "balls"),
-            Color.BOLD_ON + Color.MAGENTA + "bysen" + Color.RESET + Color.RED + " balls" + Color.RESET,
-            "some " + Color.BOLD_ON + Color.MAGENTA + "bysen" + Color.RESET + Color.RED + " balls" + Color.RESET + " are on the ground.",
-            "some " + Color.BOLD_ON + Color.MAGENTA + "bysen" + Color.RESET + Color.RED + " balls" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            2000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PLASMA_TV(40, Arrays.asList("plasma tv", "plasma"),
-            Color.BOLD_ON + Color.MAGENTA + "plasma" + Color.RESET + Color.RED + " tv" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "plasma" + Color.RESET + Color.RED + " tv" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "plasma" + Color.RESET + Color.RED + " tv" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            6000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    DOGNOSES(41, Arrays.asList("dog", "nose", "dog nose"),
-            Color.GREEN + "dog" + Color.RESET + " nose" + Color.RESET,
-            "a " + Color.GREEN + "dog" + Color.RESET + " nose" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "dog" + Color.RESET + " nose" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            2500, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    PURPLE_DRANK(42, Arrays.asList("drank", "purple drank", "p", "purple", "lean", "sizzurp"),
+    PURPLE_DRANK(10, Arrays.asList("drank", "purple drank", "p", "purple", "lean", "sizzurp"),
             "a double cup of " + MAGENTA + "purple" + RESET + " drank",
             "a double cup of " + MAGENTA + "purple" + RESET + " drank rests on the ground.",
             "a tonic called " + MAGENTA + "purple" + RESET + " drank that restores 500 health" + RESET,
@@ -478,10 +125,10 @@ public enum ItemType {
             Rarity.BASIC,
             8, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    LEATHER_SATCHEL(43, Arrays.asList("leather satchel", "satchel"),
+    LEATHER_SATCHEL(11, Arrays.asList("leather satchel", "satchel"),
             "a " + Color.GREEN + "leather satchel" + Color.RESET,
             "a " + Color.GREEN + "leather satchel" + Color.RESET,
-            "a " + Color.GREEN + "leather satchel" + Color.RESET + " with room to store 10 items.",
+            "a " + Color.GREEN + "leather satchel" + Color.RESET + " (15 items)",
             false,
             0,
             60,
@@ -489,7 +136,7 @@ public enum ItemType {
             Rarity.BASIC,
             800, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    BIGGERS_SKIN_SATCHEL(44, Arrays.asList("biggers skin satchel", "skin satchel"),
+    BIGGERS_SKIN_SATCHEL(12, Arrays.asList("biggers skin satchel", "skin satchel"),
             "a " + Color.GREEN + "biggers skin satchel" + Color.RESET,
             "a " + Color.GREEN + "biggers skin satchel" + Color.RESET,
             "a " + Color.GREEN + "biggers skin satchel" + Color.RESET + " with room to store 100 items.",
@@ -500,1261 +147,17 @@ public enum ItemType {
             Rarity.BASIC,
             3000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
 
-    STRENGTH_ELIXIR(45, Arrays.asList("strength", "strength elixir", "elixir", "s", "e"),
-            "an elixir of " + RED + "strength" + RESET,
-            "an elixir of " + RED + "strength" + RESET + " is in an crystal vessel on the ground.",
-            "an elixir of " + RED + "strength" + RESET + " that increases your might.",
-            true,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            300, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    CHRONIC_JOOSE(46, Arrays.asList("chronic", "chronic joose", "joose", "c", "j"),
-            "an elixir of " + GREEN + "chronic" + RESET + " joose",
-            "an elixir of " + GREEN + "chronic" + RESET + " joose is in an crystal vessel on the ground.",
-            "an elixir of " + GREEN + "chronic" + RESET + " joose that increases your chronic-ness.",
-            true,
-            0,
-            60,
-            true,
-            Rarity.BASIC,
-            1000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BISMUTH_SWORD(47, Arrays.asList("sword", "bismuth sword", "bismuth sword"),
-            Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            1000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BISMUTH_CHESTPLATE(48, Arrays.asList("chestplate", "a bismuth chestplate", "bismuth chestplate"),
-            Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            800000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BISMUTH_HELMET(49, Arrays.asList("helmet", "a bismuth helmet", "bismuth helmet"),
-            Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            700000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BISMUTH_BRACERS(50, Arrays.asList("bracers", "bismuth bracers", "bismuth bracers"),
-            Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            650000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BISMUTH_LEGGINGS(51, Arrays.asList("leggings", "bismuth leggings", "bismuth leggings"),
-            Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            900000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BISMUTH_BOOTS(52, Arrays.asList("boots", "bismuth boots"),
-            Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.MAGENTA + "bismuth" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.RARE,
-            800000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    GUCCI_PANTS(53, Arrays.asList("pants", "gucci pants", "gucci pants"),
-            Color.BOLD_ON + Color.CYAN + "gucci" + Color.RESET + Color.YELLOW + " pants" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "gucci" + Color.RESET + Color.YELLOW + " pants" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "gucci" + Color.RESET + Color.YELLOW + " pants" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.EXOTIC,
-            40000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    HAZE(54, Arrays.asList("haze", "lemon", "h", "l"),
-            Color.BOLD_ON + Color.YELLOW + "lemon" + Color.RESET + Color.GREEN + " haze" + Color.RESET,
-            "some " + Color.BOLD_ON + Color.YELLOW + "lemon" + Color.RESET + Color.GREEN + " haze" + Color.RESET + " flowers" + Color.RESET + " are here on the ground.",
-            "some " + Color.BOLD_ON + Color.YELLOW + "lemon" + Color.RESET + Color.GREEN + " haze" + Color.RESET + " flowers" + Color.RESET,
+    LIGHTNING_SPELLBOOKNG(13, Arrays.asList("lightning book", "lightning spell book", "book", "spell book"),
+            "a " + Color.YELLOW + "lightning" + Color.RESET + " spell book." + Color.RESET,
+            "a " + Color.YELLOW + "lightning" + Color.RESET + " spell book." + Color.RESET,
+            "a " + Color.YELLOW + "lightning" + Color.RESET + " spell book." + Color.RESET,
             true,
             0,
             60,
             false,
             Rarity.RARE,
-            5000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    YETI_CLAW(55, Arrays.asList("yeti claw", "yeti"),
-            Color.BOLD_ON + "yeti" + Color.RESET + Color.RED + " claw" + Color.RESET,
-            "a " + Color.BOLD_ON + "yeti" + Color.RESET + Color.RED + " claw" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + "yeti" + Color.RESET + Color.RED + " claw" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1100000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    CRYSTAL_DAGGER(56, Arrays.asList("crystal dagger", "dagger"),
-            Color.BOLD_ON + Color.CYAN + "crystal" + Color.RESET + Color.RED + " dagger" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "crystal" + Color.RESET + Color.RED + " dagger" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "crystal" + Color.RESET + Color.RED + " dagger" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1400000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
+            3000, Sets.<TimeTracker.TimeOfDay>newHashSet()),;
 
-    GOLDEN_WAND(57, Arrays.asList("golden wand", "golden"),
-            Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.RED + " wand" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.RED + " wand" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.RED + " wand" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1200000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    GLOWING_ORB(58, Arrays.asList("glowing orb", "orb"),
-            Color.BOLD_ON + "glowing" + Color.RESET + Color.CYAN + " orb" + Color.RESET,
-            "a " + Color.BOLD_ON + "glowing" + Color.RESET + Color.CYAN + " orb" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + "glowing" + Color.RESET + Color.CYAN + " orb" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    WOODEN_CHEST(59, Arrays.asList("wooden chest", "chest"),
-            Color.BOLD_ON + "wooden" + Color.RESET + Color.RED + " chest" + Color.RESET,
-            "a " + Color.BOLD_ON + "wooden" + Color.RESET + Color.RED + " chest" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + "wooden" + Color.RESET + Color.RED + " chest" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1100000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    ENCHANTED_SHIELD(60, Arrays.asList("enchanted shield", "enchanted"),
-            Color.BOLD_ON + Color.CYAN + "enchanted" + Color.RESET + Color.CYAN + " shield" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "enchanted" + Color.RESET + Color.CYAN + " shield" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "enchanted" + Color.RESET + Color.CYAN + " shield" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.EXOTIC,
-            50000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AMETHYST_VIAL(61, Arrays.asList("amethyst vial", "vial"),
-            Color.BOLD_ON + Color.MAGENTA + "amethyst" + Color.RESET + Color.CYAN + " vial" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "amethyst" + Color.RESET + Color.CYAN + " vial" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "amethyst" + Color.RESET + Color.CYAN + " vial" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1500000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AMETHYST_RING(62, Arrays.asList("amethyst ring", "ring"),
-            Color.BOLD_ON + Color.MAGENTA + "amethyst" + Color.RESET + Color.CYAN + " ring" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "amethyst" + Color.RESET + Color.CYAN + " ring" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "amethyst" + Color.RESET + Color.CYAN + " ring" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1800000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VULCERIUM_CHAIN(63, Arrays.asList("vulcerium chain", "chain"),
-            Color.RED + "vulcerium" + Color.RESET + Color.CYAN + " chain" + Color.RESET,
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.CYAN + " chain" + Color.RESET + " is on the ground.",
-            "a " + Color.RED + "vulcerium" + Color.RESET + Color.CYAN + " chain" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            3000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    LION_TAIL(64, Arrays.asList("lion tail", "tail"),
-            Color.BOLD_ON + "lion" + Color.RESET + Color.RED + " tail" + Color.RESET,
-            "a " + Color.BOLD_ON + "lion" + Color.RESET + Color.RED + " tail" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + "lion" + Color.RESET + Color.RED + " tail" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            2200000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SOLAR_PENDANT(65, Arrays.asList("solar pendant", "pendant"),
-            Color.BOLD_ON + Color.YELLOW + "solar" + Color.RESET + " pendant" + Color.RESET,
-            "a " + Color.BOLD_ON + "solar" + Color.RESET + " pendant" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + "solar" + Color.RESET + " pendant" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1700000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SILVER_STAR(66, Arrays.asList("silver star", "star"),
-            Color.BOLD_ON + "silver" + Color.RESET + Color.CYAN + " star" + Color.RESET,
-            "a " + Color.BOLD_ON + "silver" + Color.RESET + Color.CYAN + " star" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + "silver" + Color.RESET + Color.CYAN + " star" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            1500000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    GOLDEN_AXE(67, Arrays.asList("golden axe", "axe"),
-            Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " axe" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " axe" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " axe" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            5000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    GOLDEN_PRISM(68, Arrays.asList("golden prism", "prism"),
-            Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " prism" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " prism" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " prism" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.EXOTIC,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    OBSIDIAN_BLADE(69, Arrays.asList("obsidian blade", "blade"),
-            Color.BOLD_ON + Color.BLUE + "obsidian" + Color.RESET + Color.CYAN + " blade" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.BLUE + "obsidian" + Color.RESET + Color.CYAN + " blade" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.BLUE + "obsidian" + Color.RESET + Color.CYAN + " blade" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            4000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BOOK_OF_THORBRAND(70, Arrays.asList("Book of Thorbrand", "book", "Book"),
-            Color.BOLD_ON + Color.YELLOW + "Book" + Color.RESET + " of" + Color.CYAN + " Thorbrand" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "Book" + Color.RESET + " of" + Color.CYAN + " Thorbrand" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "Book" + Color.RESET + " of" + Color.CYAN + " Thorbrand" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            5000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    GOLDEN_HARP(71, Arrays.asList("golden harp", "harp"),
-            Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " harp" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " harp" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " harp" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            5000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SILK_SCROLL(72, Arrays.asList("silk scroll", "scroll"),
-            Color.BOLD_ON + Color.WHITE + "silk" + Color.RESET + Color.CYAN + " scroll" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.WHITE + "silk" + Color.RESET + Color.CYAN + " scroll" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.WHITE + "silk" + Color.RESET + Color.CYAN + " scroll" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            5300000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BLACK_TRUFFLE(73, Arrays.asList("black truffle", "truffle"),
-            Color.BOLD_ON + Color.BLUE + "black" + Color.RESET + Color.WHITE + Color.BOLD_ON + " truffle" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.BLUE + "black" + Color.RESET + Color.WHITE + Color.BOLD_ON + " truffle" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.BLUE + "black" + Color.RESET + Color.WHITE + Color.BOLD_ON + " truffle" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            6000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    EMERALD_STATUE(74, Arrays.asList("emerald statue", "statue"),
-            Color.BOLD_ON + Color.GREEN + "emerald" + Color.RESET + Color.CYAN + " statue" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "emerald" + Color.RESET + Color.CYAN + " statue" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "emerald" + Color.RESET + Color.CYAN + " statue" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            7000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    DEMONIC_TALISMAN(75, Arrays.asList("demonic talisman", "talisman"),
-            Color.BOLD_ON + Color.RED + "demonic" + Color.RESET + Color.CYAN + " talisman" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.RED + "demonic" + Color.RESET + Color.CYAN + " talisman" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "demonic" + Color.RESET + Color.CYAN + " talisman" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    EYE_OF_NJAL(76, Arrays.asList("Eye of Njal", "Eye", "eye"),
-            Color.BOLD_ON + Color.WHITE + "Eye" + Color.RESET + " of" + Color.RED + " Njal" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.WHITE + "Eye" + Color.RESET + " of" + Color.RED + " Njal" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.WHITE + "Eye" + Color.RESET + " of" + Color.RED + " Njal" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VALGARD_STONE(77, Arrays.asList("Valgard stone", "stone"),
-            Color.BOLD_ON + Color.YELLOW + "Valgard" + Color.RESET + Color.CYAN + " stone" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "Valgard" + Color.RESET + Color.CYAN + " stone" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "Valgard" + Color.RESET + Color.CYAN + " stone" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8300000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BLOODSTONE(78, Arrays.asList("bloodstone", "stone"),
-            Color.BOLD_ON + Color.RED + "bloodstone" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.RED + "bloodstone" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "bloodstone" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8500000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    HORN_OF_KOLSKEGG(79, Arrays.asList("Horn of Kolskegg", "Horn", "horn"),
-            Color.BOLD_ON + Color.YELLOW + "Horn" + Color.RESET + " of" + Color.CYAN + " Kolskegg" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "Horn" + Color.RESET + " of" + Color.CYAN + " Kolskegg" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "Horn" + Color.RESET + " of" + Color.CYAN + " Kolskegg" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            12000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    ANCIENT_RUNESTONE(80, Arrays.asList("ancient runestone", "runestone"),
-            Color.BOLD_ON + Color.YELLOW + "ancient" + Color.RESET + Color.WHITE + Color.BOLD_ON + " runestone" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "ancient" + Color.RESET + Color.WHITE + Color.BOLD_ON + " runestone" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "ancient" + Color.RESET + Color.WHITE + Color.BOLD_ON + " runestone" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            15000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AEGIRS_PIPE(81, Arrays.asList("Aegirs pipe", "pipe"),
-            Color.BOLD_ON + Color.YELLOW + "Aegirs" + Color.RESET + Color.CYAN + " pipe" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "Aegirs" + Color.RESET + Color.CYAN + " pipe" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "Aegirs" + Color.RESET + Color.CYAN + " pipe" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            15000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SERPENT_IDOL(82, Arrays.asList("serpent idol", "idol"),
-            Color.BOLD_ON + Color.MAGENTA + "serpent" + Color.RESET + Color.CYAN + " idol" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "serpent" + Color.RESET + Color.CYAN + " idol" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "serpent" + Color.RESET + Color.CYAN + " idol" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            20000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SORCERORS_MONOCLE(83, Arrays.asList("Sorcerors monocle", "monocle"),
-            Color.BOLD_ON + Color.RED + "Sorcerors" + Color.RESET + Color.WHITE + " monocle" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.RED + "Sorcerors" + Color.RESET + Color.WHITE + " monocle" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "Sorcerors" + Color.RESET + Color.WHITE + " monocle" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            20000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SPIDER_FANG(84, Arrays.asList("spider fang", "fang"),
-            Color.BOLD_ON + Color.YELLOW + "spider" + Color.RESET + Color.RED + " fang" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "spider" + Color.RESET + Color.RED + " fang" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "spider" + Color.RESET + Color.RED + " fang" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            25000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    SPIDERSILK_POUCH(85, Arrays.asList("spidersilk pouch", "pouch"),
-            Color.BOLD_ON + Color.YELLOW + "spidersilk" + Color.RESET + Color.CYAN + " pouch" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.YELLOW + "spidersilk" + Color.RESET + Color.CYAN + " pouch" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.YELLOW + "spidersilk" + Color.RESET + Color.CYAN + " pouch" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            30000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    CRYSTAL_SPIDER(86, Arrays.asList("crystal spider", "spider"),
-            Color.BOLD_ON + Color.CYAN + "crystal" + Color.RESET + Color.RED + " spider" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "crystal" + Color.RESET + Color.RED + " spider" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "crystal" + Color.RESET + Color.RED + " spider" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            32000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-    
-    AEXIUM_SWORD(87, Arrays.asList("sword", "aexium sword", "aexium sword"),
-            Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            2000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AEXIUM_CHESTPLATE(88, Arrays.asList("chestplate", "a aexium chestplate", "aexium chestplate"),
-            Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " chestplate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            1800000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AEXIUM_HELMET(89, Arrays.asList("helmet", "a aexium helmet", "aexium helmet"),
-            Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            1700000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AEXIUM_BRACERS(90, Arrays.asList("bracers", "aexium bracers", "aexium bracers"),
-            Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            1650000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AEXIUM_LEGGINGS(91, Arrays.asList("leggings", "aexium leggings", "aexium leggings"),
-            Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " leggings" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            1900000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    AEXIUM_BOOTS(92, Arrays.asList("boots", "aexium boots"),
-            Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.CYAN + "aexium" + Color.RESET + Color.YELLOW + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.RARE,
-            1800000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    AEXIRIAN_ROOT(93, Arrays.asList("aexirian", "root", "a", "r", "aexirian root"),
-            Color.GREEN + "aexirian" + Color.RESET + " root" + Color.RESET,
-            "an " + Color.GREEN + "aexirian" + Color.RESET + " root" + Color.RESET + " is here on the ground.",
-            "an " + Color.GREEN + "aexirian" + Color.RESET + " root" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    MITHAEM_LEAF(94, Arrays.asList("mithaem", "leaf", "m", "l", "mithaem leaf"),
-            Color.GREEN + "mithaem" + Color.RESET + " leaf" + Color.RESET,
-            "a " + Color.GREEN + "mithaem" + Color.RESET + " leaf" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "mithaem" + Color.RESET + " leaf" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    DURICCA_ROOT(95, Arrays.asList("duricca", "root", "d", "r", "duricca root"),
-            Color.GREEN + "duricca" + Color.RESET + " root" + Color.RESET,
-            "a " + Color.GREEN + "duricca" + Color.RESET + " root" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "duricca" + Color.RESET + " root" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-    
-    PONDESEL_BERRY(96, Arrays.asList("pondesel", "berry", "p", "b", "pondesel berry"),
-            Color.GREEN + "pondesel" + Color.RESET + " berry" + Color.RESET,
-            "a " + Color.GREEN + "pondesel" + Color.RESET + " berry" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "pondesel" + Color.RESET + " berry" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),      
-
-    VIKALIONUS_CAP(97, Arrays.asList("vikalionus", "cap", "v", "c", "vikalionus cap"),
-            Color.GREEN + "vikalionus" + Color.RESET + " cap" + Color.RESET,
-            "a " + Color.GREEN + "vikalionus" + Color.RESET + " cap" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "vikalionus" + Color.RESET + " cap" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    LOORNS_LACE(98, Arrays.asList("loorn's", "lace", "l", "loorn's lace"),
-            Color.GREEN + "loorn's" + Color.RESET + " lace" + Color.RESET,
-            "some " + Color.GREEN + "loorn's" + Color.RESET + " lace" + Color.RESET + " is here on the ground.",
-            "some " + Color.GREEN + "loorn's" + Color.RESET + " lace" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    TOURNEARES_LEAF(99, Arrays.asList("tourneares", "leaf", "t", "l", "tourneares leaf"),
-            Color.GREEN + "tourneares" + Color.RESET + " leaf" + Color.RESET,
-            "a " + Color.GREEN + "tourneares" + Color.RESET + " leaf" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "tourneares" + Color.RESET + " leaf" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    HAUSSIAN_BERRY(100, Arrays.asList("haussian", "berry", "h", "b", "haussian berry"),
-            Color.GREEN + "haussian" + Color.RESET + " berry" + Color.RESET,
-            "a " + Color.GREEN + "haussian" + Color.RESET + " berry" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "haussian" + Color.RESET + " berry" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    PERTILLIUM_ROOT(101, Arrays.asList("pertillium", "root", "p", "r", "pertillium root"),
-            Color.GREEN + "pertillium" + Color.RESET + " root" + Color.RESET,
-            "some " + Color.GREEN + "pertillium" + Color.RESET + " root" + Color.RESET + " is here on the ground.",
-            "some " + Color.GREEN + "pertillium" + Color.RESET + " root" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    HYCIANTHIS_BARK(102, Arrays.asList("hycianthis", "bark", "h", "b", "hycianthis bark"),
-            Color.GREEN + "hycianthis" + Color.RESET + " bark" + Color.RESET,
-            "some " + Color.GREEN + "hycianthis" + Color.RESET + " bark" + Color.RESET + " is here on the ground.",
-            "some " + Color.GREEN + "hycianthis" + Color.RESET + " bark" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    PUNILARE_FERN(103, Arrays.asList("punilare", "fern", "p", "f", "punilare fern"),
-            Color.GREEN + "punilare" + Color.RESET + " fern" + Color.RESET,
-            "a " + Color.GREEN + "punilare" + Color.RESET + " fern" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "punilare" + Color.RESET + " fern" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    KEAKIAR_CAP(104, Arrays.asList("keakiar", "cap", "k", "c", "keakiar cap"),
-            Color.GREEN + "keakiar" + Color.RESET + " cap" + Color.RESET,
-            "a " + Color.GREEN + "keakiar" + Color.RESET + " cap" + Color.RESET + " is here on the ground.",
-            "a " + Color.GREEN + "keakiar" + Color.RESET + " cap" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.BASIC,
-            80, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    DIRTY_BOMB(105, Arrays.asList("dirty bomb", "bomb"),
-            Color.YELLOW + "dirty" + Color.RESET + " bomb" + Color.RESET,
-            "a " + Color.YELLOW + "dirty" + Color.RESET + " bomb" + Color.RESET + " is here on the ground.",
-            "a " + Color.YELLOW + "dirty" + Color.RESET + " bomb" + Color.RESET,
-            true,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            4000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    JADE_FLASK(106, Arrays.asList("jade flask", "jade", "flask", "j", "f"),
-            Color.BOLD_ON + Color.GREEN + "jade" + Color.RESET + Color.WHITE + " flask" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "jade" + Color.RESET + Color.WHITE + " flask" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "jade" + Color.RESET + Color.WHITE + " flask" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    HYCIANTHIS_FLUTE(107, Arrays.asList("hycianthis flute", "flute", "h", "f", "hycianthis"),
-            Color.BOLD_ON + Color.GREEN + "hycianthis" + Color.RESET + Color.RED + " flute" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "hycianthis" + Color.RESET + Color.RED + " flute" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "hycianthis" + Color.RESET + Color.RED + " flute" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    CURSED_MIRROR(108, Arrays.asList("cursed", "mirror", "m", "c", "cursed mirror"),
-            Color.BOLD_ON + Color.RED + "cursed" + Color.RESET + Color.CYAN + " mirror" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.RED + "cursed" + Color.RESET + Color.CYAN + " mirror" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "cursed" + Color.RESET + Color.CYAN + " mirror" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    IVORY_DART(109, Arrays.asList("ivory dart", "dart", "i", "d", "ivory"),
-            Color.BOLD_ON + Color.WHITE + "ivory" + Color.RESET + Color.MAGENTA + " dart" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.WHITE + "ivory" + Color.RESET + Color.MAGENTA + " dart" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.WHITE + "ivory" + Color.RESET + Color.MAGENTA + " dart" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    VULCERIUM_ICEAXE(110, Arrays.asList("vulcerium ice axe", "ice axe", "axe", "v", "ice", "a"),
-            Color.BOLD_ON + Color.RED + "vulcerium" + Color.RESET + Color.CYAN + " ice " + Color.RESET + "axe",
-            "a " + Color.BOLD_ON + Color.RED + "vulcerium" + Color.RESET + Color.CYAN + " ice " + Color.RESET + "axe is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "vulcerium" + Color.RESET + Color.CYAN + " ice " + Color.RESET + "axe",
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    HELGIS_POTION(111, Arrays.asList("Helgi's potion", "potion", "Helgi's", "H", "p"),
-            Color.BOLD_ON + Color.RED + "Helgi's" + Color.RESET + Color.MAGENTA + Color.BOLD_ON + " potion" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.RED + "Helgi's" + Color.RESET + Color.MAGENTA + Color.BOLD_ON + " potion" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "Helgi's" + Color.RESET + Color.MAGENTA + Color.BOLD_ON + " potion" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    CELESTIAL_DIAL(112, Arrays.asList("celestial dial", "dial", "c", "d", "celestial"),
-            Color.BOLD_ON + Color.CYAN + "celestial" + Color.RESET + Color.WHITE + Color.BOLD_ON + " dial" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.CYAN + "celestial" + Color.RESET + Color.WHITE + Color.BOLD_ON + " dial" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.CYAN + "celestial" + Color.RESET + Color.WHITE + Color.BOLD_ON + " dial" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    THORS_LANTERN(113, Arrays.asList("Thor's lantern", "lantern", "Thor's", "T", "l"),
-            Color.BOLD_ON + Color.RED + "Thor's" + Color.RESET + Color.YELLOW + " lantern" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.RED + "Thor's" + Color.RESET + Color.YELLOW + " lantern" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.RED + "Thor's" + Color.RESET + Color.YELLOW + " lantern" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    ORNATE_CROWN(114, Arrays.asList("ornate crown", "crown", "o", "c", "ornate"),
-            Color.BOLD_ON + Color.MAGENTA + "ornate" + Color.RESET + Color.YELLOW + " crown" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.MAGENTA + "ornate" + Color.RESET + Color.YELLOW + " crown" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.MAGENTA + "ornate" + Color.RESET + Color.YELLOW + " crown" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    PYAMITE_COMPASS(115, Arrays.asList("pyamite compass", "compass", "p", "c", "pyamite"),
-            Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " compass" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " compass" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " compass" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    PYAMITE_ICEAXE(116, Arrays.asList("pyamite ice axe", "ice axe", "axe", "p", "ice", "a"),
-            Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " ice " + Color.RESET + "axe",
-            "a " + Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " ice " + Color.RESET + "axe is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " ice " + Color.RESET + "axe",
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    IRON_LOCKPICKING_SET(117, Arrays.asList("iron lockpicking set", "lockpicking set", "set", "lockpicking", "i", "l", "s"),
-            Color.WHITE + "iron" + Color.RESET + Color.CYAN + " lockpicking " + Color.RESET + "set",
-            "an " + Color.WHITE + "iron" + Color.RESET + Color.CYAN + " lockpicking " + Color.RESET + "set is on the ground.",
-            "an " + Color.WHITE + "iron" + Color.RESET + Color.CYAN + " lockpicking " + Color.RESET + "set",
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    PYAMITE_LOCKPICKING_SET(118, Arrays.asList("pyamite lockpicking set", "lockpicking set", "set", "lockpicking", "p", "l", "s"),
-            Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " lockpicking " + Color.RESET + "set",
-            "a " + Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " lockpicking " + Color.RESET + "set is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "pyamite" + Color.RESET + Color.CYAN + " lockpicking " + Color.RESET + "set",
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SPOOL_OF_CLIMBING_ROPE(119, Arrays.asList("spool of climbing rope", "spool", "climbing rope", "rope", "s", "r"),
-            Color.WHITE + "spool of" + Color.RESET + Color.CYAN + " climbing " + Color.RESET + "rope",
-            "a " + Color.WHITE + "spool of" + Color.RESET + Color.CYAN + " climbing " + Color.RESET + "rope is on the ground.",
-            "a " + Color.WHITE + "spool of" + Color.RESET + Color.CYAN + " climbing " + Color.RESET + "rope",
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    BLACK_CLOAK(120, Arrays.asList("black cloak", "black", "cloak", "b", "c"),
-            Color.BOLD_ON + Color.BLACK + "black" + Color.RESET + Color.CYAN + " cloak" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.BLACK + "black" + Color.RESET + Color.CYAN + " cloak " + Color.RESET + "is on the ground.",
-            "a " + Color.BOLD_ON + Color.BLACK + "black" + Color.RESET + Color.CYAN + " cloak " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SMELTING_CRUCIBLE(121, Arrays.asList("smelting crucible", "crucible", "smelting", "s", "c"),
-            Color.WHITE + "smelting" + Color.RESET + Color.CYAN + " crucible " + Color.RESET,
-            "a " + Color.WHITE + "smelting" + Color.RESET + Color.CYAN + " crucible " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "smelting" + Color.RESET + Color.CYAN + " crucible " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    LEATHER_SHOES(122, Arrays.asList("leather shoes", "leather", "shoes", "l", "s"),
-            Color.WHITE + "leather" + Color.RESET + Color.CYAN + " shoes" + Color.RESET,
-            "some " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " shoes " + Color.RESET + "are on the ground.",
-            "some " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " shoes " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    GENTLEMANS_TOP_HAT(123, Arrays.asList("gentleman's top hat", "top hat", "hat", "g", "t", "h"),
-            Color.WHITE + "gentleman's" + Color.RESET + Color.CYAN + " top hat" + Color.RESET,
-            "a " + Color.WHITE + "gentleman's" + Color.RESET + Color.CYAN + " top hat " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "gentleman's" + Color.RESET + Color.CYAN + " top hat " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    LEATHER_GLOVES(124, Arrays.asList("leather gloves", "leather", "gloves", "l", "g"),
-            Color.WHITE + "leather" + Color.RESET + Color.CYAN + " gloves " + Color.RESET,
-            "a pair of " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " gloves " + Color.RESET + "is on the ground.",
-            "a pair of " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " gloves " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    WOOL_SCARF(125, Arrays.asList("wool scarf", "wool", "scarf", "w", "s"),
-            Color.WHITE + "wool" + Color.RESET + Color.CYAN + " scarf " + Color.RESET,
-            "a " + Color.WHITE + "wool" + Color.RESET + Color.CYAN + " scarf " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "wool" + Color.RESET + Color.CYAN + " scarf " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    LEATHER_BELT(126, Arrays.asList("leather belt", "leather", "belt", "l", "b"),
-            Color.WHITE + "leather" + Color.RESET + Color.CYAN + " belt " + Color.RESET,
-            "a " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " belt " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " belt " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SILK_SASH(127, Arrays.asList("silk sash", "silk", "sash", "s"),
-            Color.WHITE + "silk" + Color.RESET + Color.CYAN + " sash " + Color.RESET,
-            "a " + Color.WHITE + "silk" + Color.RESET + Color.CYAN + " sash " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "silk" + Color.RESET + Color.CYAN + " sash " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    LEATHER_SCABBARD(128, Arrays.asList("leather scabbard", "leather", "scabbard", "s", "l"),
-            Color.WHITE + "leather" + Color.RESET + Color.CYAN + " scabbard " + Color.RESET,
-            "a " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " scabbard " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "leather" + Color.RESET + Color.CYAN + " scabbard " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    BYSENSKIN_SCABBARD(129, Arrays.asList("bysen skin scabbard", "bysen skin", "scabbard", "s", "b"),
-            Color.WHITE + "bysen skin" + Color.RESET + Color.CYAN + " scabbard " + Color.RESET,
-            "a " + Color.WHITE + "bysen skin" + Color.RESET + Color.CYAN + " scabbard " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "bysen skin" + Color.RESET + Color.CYAN + " scabbard " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    IRON_SPECTACLES(130, Arrays.asList("iron spectacles", "iron", "spectacles", "i", "s"),
-            Color.WHITE + "iron" + Color.RESET + Color.CYAN + " spectacles " + Color.RESET,
-            "a pair of " + Color.WHITE + "iron" + Color.RESET + Color.CYAN + " spectacles " + Color.RESET + "are on the ground.",
-            "a pair of " + Color.WHITE + "iron" + Color.RESET + Color.CYAN + " spectacles " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    GOLDEN_SPECTACLES(131, Arrays.asList("golden spectacles", "golden", "spectacles", "s", "g"),
-            Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " spectacles " + Color.RESET,
-            "a pair of " + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " spectacles " + Color.RESET + "are on the ground.",
-            "a pair of " + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " spectacles " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    NOBLEMANS_SHOULDER_CLASP(132, Arrays.asList("nobleman's shoulder clasp", "nobleman's", "shoulder clasp", "clasp", "n", "s", "c"),
-            Color.MAGENTA + "nobleman's" + Color.RESET + Color.CYAN + " shoulder clasp " + Color.RESET,
-            "a " + Color.MAGENTA + "nobleman's" + Color.RESET + Color.CYAN + " shoulder clasp " + Color.RESET + "is on the ground.",
-            "a " + Color.MAGENTA + "nobleman's" + Color.RESET + Color.CYAN + " shoulder clasp " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    WOODSMANS_TUNIC(133, Arrays.asList("woodsman's tunic", "woodsman's", "tunic", "w", "t"),
-            Color.WHITE + "woodsman's" + Color.RESET + Color.CYAN + " tunic " + Color.RESET,
-            "a " + Color.WHITE + "woodsman's" + Color.RESET + Color.CYAN + " tunic " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "woodsman's" + Color.RESET + Color.CYAN + " tunic " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    PLAIN_WHITE_ROBE(134, Arrays.asList("plain white robe", "white robe", "robe", "w", "r"),
-            Color.WHITE + "plain white" + Color.RESET + Color.CYAN + " robe " + Color.RESET,
-            "a " + Color.WHITE + "plain white" + Color.RESET + Color.CYAN + " robe " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "plain white" + Color.RESET + Color.CYAN + " robe " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    FINE_POWDERED_WIG(135, Arrays.asList("fine powdered wig", "powdered wig", "wig", "p", "w"),
-            Color.WHITE + "fine powdered" + Color.RESET + Color.CYAN + " wig " + Color.RESET,
-            "a " + Color.WHITE + "fine powdered" + Color.RESET + Color.CYAN + " wig " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "fine powdered" + Color.RESET + Color.CYAN + " wig " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    HABROK_FEATHER_HAT(136, Arrays.asList("habrok feather hat", "feather hat", "hat", "f", "h"),
-            Color.WHITE + "habrok feather" + Color.RESET + Color.CYAN + " hat " + Color.RESET,
-            "a " + Color.WHITE + "habrok feather" + Color.RESET + Color.CYAN + " hat " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "habrok feather" + Color.RESET + Color.CYAN + " hat " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    POLISHED_IRON_CODPIECE(137, Arrays.asList("polished iron codpiece", "iron codpiece", "codpiece", "i", "c"),
-            Color.WHITE + "polished iron" + Color.RESET + Color.CYAN + " codpiece " + Color.RESET,
-            "a " + Color.WHITE + "polished iron" + Color.RESET + Color.CYAN + " codpiece " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "polished iron" + Color.RESET + Color.CYAN + " codpiece " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    GOLDEN_CODPIECE(138, Arrays.asList("golden codpiece", "codpiece", "golden", "g", "c"),
-            Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " codpiece " + Color.RESET,
-            "a shimmering " + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " codpiece " + Color.RESET + "is on the ground.",
-            "a shimmering " + Color.YELLOW + "golden" + Color.RESET + Color.CYAN + " codpiece " + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VIAGRA_SWORD(139, Arrays.asList("sword", "viagra sword", "viagra sword"),
-            Color.GREEN + "viagra" + Color.RESET + Color.RED + " sword" + Color.RESET,
-            "a " + Color.GREEN + "viagra" + Color.RESET + Color.RED + " sword" + Color.RESET + " is on the ground.",
-            "a " + Color.GREEN + "viagra" + Color.RESET + Color.RED + " sword" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    RADSUIT_CHESTPLATE(140, Arrays.asList("chestplate", "a radsuit chestplate", "radsuit chestplate", "radsuit"),
-            Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " chestplate" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " chestplate" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " chestplate" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    RADSUIT_HELMET(141, Arrays.asList("helmet", "a radsuit helmet", "radsuit helmet", "radsuit"),
-            Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " helmet" + Color.RESET,
-            "a " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " helmet" + Color.RESET + " is on the ground.",
-            "a " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " helmet" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    RADSUIT_BRACERS(142, Arrays.asList("bracers", "radsuit bracers", "radsuit"),
-            Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " bracers" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " bracers" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " bracers" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    RADSUIT_LEGGINGS(143, Arrays.asList("leggings", "radsuit leggings", "radsuit"),
-            Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " leggings" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " leggings" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " leggings" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    RADSUIT_BOOTS(144, Arrays.asList("boots", "radsuit boots", "radsuit"),
-            Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " boots" + Color.RESET,
-            "a pair of " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " boots" + Color.RESET + " are on the ground.",
-            "a pair of " + Color.BOLD_ON + Color.GREEN + "radsuit" + Color.RESET + Color.MAGENTA + " boots" + Color.RESET,
-            false,
-            0,
-            60,
-            true,
-            Rarity.LEGENDARY,
-            100000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    CRYSTALLINE_TABLET(145, Arrays.asList("crystalline tablet", "crystalline", "tablet", "c", "t"),
-            Color.CYAN + "crystalline" + Color.RESET + Color.YELLOW + " tablet" + Color.RESET,
-            "a " + Color.CYAN + "crystalline" + Color.RESET + Color.YELLOW + " tablet " + Color.RESET + "is on the ground.",
-            "a " + Color.CYAN + "golden" + Color.RESET + Color.YELLOW + " tablet" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    STRAND_OF_ALYXITE(146, Arrays.asList("strand of alyxite", "strand", "alyxite", "s", "a"),
-            Color.WHITE + "strand of" + Color.RESET + Color.BOLD_ON + Color.RED + " alyxite" + Color.RESET,
-            "a " + Color.WHITE + "strand of" + Color.RESET + Color.BOLD_ON + Color.RED + " alyxite " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "strand of" + Color.RESET + Color.BOLD_ON + Color.RED + " alyxite" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    GARMR_HIDE(147, Arrays.asList("garmr hide", "garmr", "hide", "g", "h"),
-            Color.WHITE + "garmr" + Color.RESET + Color.BOLD_ON + Color.RED + " hide" + Color.RESET,
-            "a " + Color.WHITE + "garmr" + Color.RESET + Color.BOLD_ON + Color.RED + " hide " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + "garmr" + Color.RESET + Color.BOLD_ON + Color.RED + " hide" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    STROMAN_GRAVER(148, Arrays.asList("stroman graver", "stroman", "graver", "s", "g"),
-            Color.RED + Color.BOLD_ON + "stroman" + Color.RESET + Color.BOLD_ON + Color.GREEN + " graver" + Color.RESET,
-            "a " + Color.RED + Color.BOLD_ON + "stroman" + Color.RESET + Color.BOLD_ON + Color.GREEN + " graver " + Color.RESET + "is on the ground.",
-            "a " + Color.RED + Color.BOLD_ON + "stroman" + Color.RESET + Color.BOLD_ON + Color.GREEN + " graver" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    VOLCANIC_GYROSCOPE(149, Arrays.asList("volcanic gyroscope", "volcanic", "gyroscope", "v", "g"),
-            Color.BLACK + Color.BOLD_ON + "volcanic" + Color.RESET + Color.BOLD_ON + Color.CYAN + " gyroscope" + Color.RESET,
-            "a " + Color.BLACK + Color.BOLD_ON + "volcanic" + Color.RESET + Color.BOLD_ON + Color.CYAN + " gyroscope " + Color.RESET + "is on the ground.",
-            "a " + Color.BLACK + Color.BOLD_ON + "volcanic" + Color.RESET + Color.BOLD_ON + Color.CYAN + " gyroscope" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-
-    BASALT_WAND(150, Arrays.asList("basalt wand", "basalt", "wand", "b", "w"),
-            Color.BLACK + Color.BOLD_ON + "basalt" + Color.RESET + Color.BOLD_ON + Color.RED + " wand" + Color.RESET,
-            "a " + Color.BLACK + Color.BOLD_ON + "basalt" + Color.RESET + Color.BOLD_ON + Color.RED + " wand " + Color.RESET + "is on the ground.",
-            "a " + Color.BLACK + Color.BOLD_ON + "basalt" + Color.RESET + Color.BOLD_ON + Color.RED + " wand" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SPIRAL_MAGNET(151, Arrays.asList("spiral magnet", "spiral", "magnet", "s", "m"),
-            Color.GREEN + Color.BOLD_ON + "spiral" + Color.RESET + Color.BOLD_ON + Color.BLACK + " magnet" + Color.RESET,
-            "a " + Color.GREEN + Color.BOLD_ON + "spiral" + Color.RESET + Color.BOLD_ON + Color.BLACK + " magnet " + Color.RESET + "is on the ground.",
-            "a " + Color.GREEN + Color.BOLD_ON + "spiral" + Color.RESET + Color.BOLD_ON + Color.BLACK + " magnet" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SANDSTONE_RUNE(152, Arrays.asList("sandstone rune", "sandstone", "rune", "s", "r"),
-            Color.YELLOW + Color.BOLD_ON + "sandstone" + Color.RESET + Color.BOLD_ON + Color.BLACK + " rune" + Color.RESET,
-            "a " + Color.YELLOW + Color.BOLD_ON + "sandstone" + Color.RESET + Color.BOLD_ON + Color.BLACK + " rune " + Color.RESET + "is on the ground.",
-            "a " + Color.YELLOW + Color.BOLD_ON + "sandstone" + Color.RESET + Color.BOLD_ON + Color.BLACK + " rune" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SERRATED_TALON(153, Arrays.asList("serrated talon", "serrated", "talon", "s", "t"),
-            Color.WHITE + Color.BOLD_ON + "serrated" + Color.RESET + Color.BOLD_ON + Color.RED + " talon" + Color.RESET,
-            "a " + Color.WHITE + Color.BOLD_ON + "serrated" + Color.RESET + Color.BOLD_ON + Color.RED + " talon " + Color.RESET + "is on the ground.",
-            "a " + Color.WHITE + Color.BOLD_ON + "serrated" + Color.RESET + Color.BOLD_ON + Color.RED + " talon" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    GOLDEN_AMULET(154, Arrays.asList("golden amulet", "golden", "amulet", "g", "a"),
-            Color.YELLOW + Color.BOLD_ON + "golden" + Color.RESET + Color.BOLD_ON + Color.MAGENTA + " amulet" + Color.RESET,
-            "a " + Color.YELLOW + Color.BOLD_ON + "golden" + Color.RESET + Color.BOLD_ON + Color.MAGENTA + " amulet " + Color.RESET + "is on the ground.",
-            "a " + Color.YELLOW + Color.BOLD_ON + "golden" + Color.RESET + Color.BOLD_ON + Color.MAGENTA + " amulet" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    RUBY_CROWN(155, Arrays.asList("ruby crown", "ruby", "crown", "r", "c"),
-            Color.RED + Color.BOLD_ON + "ruby" + Color.RESET + Color.BOLD_ON + Color.YELLOW + " crown" + Color.RESET,
-            "a " + Color.RED + Color.BOLD_ON + "ruby" + Color.RESET + Color.BOLD_ON + Color.YELLOW + " crown " + Color.RESET + "is on the ground.",
-            "a " + Color.RED + Color.BOLD_ON + "ruby" + Color.RESET + Color.BOLD_ON + Color.YELLOW + " crown" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    POTION_OF_CLARITY(156, Arrays.asList("potion of clarity", "potion", "clarity", "p", "c"),
-            Color.MAGENTA + Color.BOLD_ON + "potion" + Color.RESET + " of" + Color.BOLD_ON + Color.CYAN + " clarity" + Color.RESET,
-            "a " + Color.MAGENTA + Color.BOLD_ON + "potion" + Color.RESET + " of" + Color.BOLD_ON + Color.CYAN + " clarity " + Color.RESET + "is on the ground.",
-            "a " + Color.MAGENTA + Color.BOLD_ON + "potion" + Color.RESET + " of" + Color.BOLD_ON + Color.CYAN + " clarity" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    LENS_OF_TIME(157, Arrays.asList("lens of time", "lens", "time", "l", "t"),
-            Color.CYAN + Color.BOLD_ON + "lens" + Color.RESET + " of" + Color.BOLD_ON + Color.RED + " time" + Color.RESET,
-            "a " + Color.CYAN + Color.BOLD_ON + "lens" + Color.RESET + " of" + Color.BOLD_ON + Color.RED + " time " + Color.RESET + "is on the ground.",
-            "a " + Color.CYAN + Color.BOLD_ON + "lens" + Color.RESET + " of" + Color.BOLD_ON + Color.RED + " time" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
-            
-    SAUSAGE_STUFFER(158, Arrays.asList("sausage stuffer", "sausage", "stuffer", "s"),
-            Color.RED + Color.BOLD_ON + "sausage" + Color.RESET + Color.BOLD_ON + Color.RED + " stuffer" + Color.RESET,
-            "a " + Color.RED + Color.BOLD_ON + "sausage" + Color.RESET + Color.BOLD_ON + Color.RED + " stuffer " + Color.RESET + "is on the ground.",
-            "a " + Color.RED + Color.BOLD_ON + "sausage" + Color.RESET + Color.BOLD_ON + Color.RED + " stuffer" + Color.RESET,
-            false,
-            0,
-            60,
-            false,
-            Rarity.LEGENDARY,
-            8000000, Sets.<TimeTracker.TimeOfDay>newHashSet());
-            
-    
             
     private final Integer itemTypeCode;
     private final List<String> itemTriggers;
@@ -1787,7 +190,7 @@ public enum ItemType {
     public Item create() {
         Item newItem = new Item(getItemName(), getItemDescription(), getItemTriggers(), getRestingName(), UUID.randomUUID().toString(), getItemTypeCode(), 0, false, itemHalfLifeTicks, getRarity(), getValueInGold());
         if (isEquipment) {
-            return EquipmentBuilder.Build(newItem);
+            return EquipmentBuilder.build(newItem);
         }
         return newItem;
     }
diff --git a/src/main/java/com/comandante/creeper/Items/ItemUseAction.java b/src/main/java/com/comandante/creeper/Items/ItemUseAction.java
index ac65a53ee2d13c3a30d0b247a4405a676a53500a..e30cb3254fd368808d8773407912e86c134271a8 100644
--- a/src/main/java/com/comandante/creeper/Items/ItemUseAction.java
+++ b/src/main/java/com/comandante/creeper/Items/ItemUseAction.java
@@ -7,12 +7,12 @@ import com.comandante.creeper.spells.Effect;
 import java.util.Set;
 
 public interface ItemUseAction {
-    public Integer getItemTypeId();
+    Integer getItemTypeId();
 
-    public void executeAction(GameManager gameManager, Player player, Item item);
+    void executeAction(GameManager gameManager, Player player, Item item);
 
-    public void postExecuteAction(GameManager gameManager, Player player, Item item);
+    void postExecuteAction(GameManager gameManager, Player player, Item item);
 
-    public Set<Effect> getEffects();
+    Set<Effect> getEffects();
 
 }
diff --git a/src/main/java/com/comandante/creeper/Items/ItemUseHandler.java b/src/main/java/com/comandante/creeper/Items/ItemUseHandler.java
index 83df53a475659945ba71f38acf80a4dc1d44d766..21a1b3abc5aea32306bf328b0107d4b16b52d804 100644
--- a/src/main/java/com/comandante/creeper/Items/ItemUseHandler.java
+++ b/src/main/java/com/comandante/creeper/Items/ItemUseHandler.java
@@ -1,14 +1,15 @@
 package com.comandante.creeper.Items;
 
 
+import com.comandante.creeper.Items.use.DefaultApplyStatsAction;
+import com.comandante.creeper.Items.use.LightningSpellBookUseAction;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
-import com.comandante.creeper.server.CreeperSession;
-import com.comandante.creeper.spells.Effect;
+import com.comandante.creeper.stat.Stats;
+import com.comandante.creeper.stat.StatsBuilder;
+import com.google.common.collect.Sets;
 import org.apache.log4j.Logger;
 
-import java.util.Set;
-
 public class ItemUseHandler {
 
     private static final Logger log = Logger.getLogger(ItemUseHandler.class);
@@ -19,10 +20,36 @@ public class ItemUseHandler {
     }
 
     public void handle(Player player, Item item) {
-        ItemUseAction itemUseAction = ItemUseRegistry.getItemUseAction(item.getItemTypeId());
+        ItemUseAction itemUseAction = null;
+        switch (ItemType.itemTypeFromCode(item.getItemTypeId())) {
+            case LIGHTNING_SPELLBOOKNG:
+                itemUseAction = new LightningSpellBookUseAction(ItemType.LIGHTNING_SPELLBOOKNG);
+                break;
+            case PURPLE_DRANK:
+                itemUseAction = new DefaultApplyStatsAction(ItemType.PURPLE_DRANK, buildStats(500, 0), Sets.newHashSet());
+                break;
+            case MARIJUANA:
+                itemUseAction = new DefaultApplyStatsAction(ItemType.MARIJUANA, buildStats(500, 500), Sets.newHashSet());
+                break;
+            case SMALL_HEALTH_POTION:
+                itemUseAction = new DefaultApplyStatsAction(ItemType.SMALL_HEALTH_POTION, buildStats(100, 0), Sets.newHashSet());
+                break;
+        }
         if (itemUseAction != null) {
             itemUseAction.executeAction(gameManager, player, item);
             itemUseAction.postExecuteAction(gameManager, player, item);
         }
     }
+
+    private static Stats buildStats(int health, int mana) {
+        StatsBuilder statsBuilder = new StatsBuilder();
+        statsBuilder.setCurrentHealth(health);
+        statsBuilder.setCurrentMana(mana);
+        return statsBuilder.createStats();
+    }
+
+    public static void incrementUses(Item item) {
+        item.setNumberOfUses(item.getNumberOfUses() + 1);
+    }
 }
+
diff --git a/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java b/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java
deleted file mode 100644
index 568fb5a564235729755474d4bbc226cd6a599144..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.comandante.creeper.Items;
-
-import com.comandante.creeper.Items.use.DefaultApplyStatsAction;
-import com.comandante.creeper.Items.use.DirtyBombUseAction;
-import com.comandante.creeper.Items.use.ResetAllEffectsUseAction;
-import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.player.Player;
-import com.comandante.creeper.spells.Effect;
-import com.comandante.creeper.stat.Stats;
-import com.comandante.creeper.stat.StatsBuilder;
-import com.google.api.client.util.Maps;
-import com.google.api.client.util.Sets;
-import org.apache.log4j.Logger;
-
-import java.util.Map;
-import java.util.Set;
-
-public class ItemUseRegistry {
-
-    private static final Map<Integer, ItemUseAction> itemUseActionMap = Maps.newHashMap();
-    private static final Logger log = Logger.getLogger(ItemUseRegistry.class);
-
-
-    public static void addItemUseAction(ItemUseAction itemUseAction) {
-        itemUseActionMap.put(itemUseAction.getItemTypeId(), itemUseAction);
-    }
-
-    public static ItemUseAction getItemUseAction(Integer id) {
-        return itemUseActionMap.get(id);
-    }
-
-    public static void configure() {
-        //Beer
-        addItemUseAction(new DefaultApplyStatsAction(ItemType.BEER, buildStats(100, 0), Sets.<Effect>newHashSet()));
-
-        //Purple Drank
-        addItemUseAction(new DefaultApplyStatsAction(ItemType.PURPLE_DRANK, buildStats(500, 0), Sets.<Effect>newHashSet()));
-
-        //Marijuana
-        addItemUseAction(new DefaultApplyStatsAction(ItemType.MARIJUANA, buildStats(500,500), Sets.<Effect>newHashSet()));
-
-        //Dog Dick
-        addItemUseAction(new DefaultApplyStatsAction(ItemType.DOGNOSES, buildStats(500,500), Sets.<Effect>newHashSet()));
-        
-        //Lemon Haze
-        addItemUseAction(new DefaultApplyStatsAction(ItemType.HAZE, buildStats(1000000,1000000), Sets.<Effect>newHashSet()));
-        
-        //Mithaem Leaf
-        addItemUseAction(new ResetAllEffectsUseAction(ItemType.MITHAEM_LEAF));
-
-        //Dirty Bomb
-        addItemUseAction(new DirtyBombUseAction(ItemType.DIRTY_BOMB));
-    }
-
-    private static Stats buildStats(int health, int mana) {
-        StatsBuilder statsBuilder = new StatsBuilder();
-        statsBuilder.setCurrentHealth(health);
-        statsBuilder.setCurrentMana(mana);
-        return statsBuilder.createStats();
-    }
-
-
-    public static void processEffects(GameManager gameManager, Player player, Set<Effect> effects) {
-        if (effects == null) {
-            return;
-        }
-        for (Effect effect : effects) {
-            Effect nEffect = new Effect(effect);
-            nEffect.setPlayerId(player.getPlayerId());
-            gameManager.getEntityManager().saveEffect(nEffect);
-            boolean effectResult = player.addEffect(nEffect.getEntityId());
-            if (effect.getDurationStats() != null) {
-                if (effect.getDurationStats().getCurrentHealth() < 0) {
-                    log.error("ERROR! Someone added an effect with a health modifier which won't work for various reasons.");
-                    continue;
-                }
-            }
-            if (effectResult) {
-                gameManager.getChannelUtils().write(player.getPlayerId(), "You feel " + effect.getEffectName() + "\r\n");
-            } else {
-                gameManager.getChannelUtils().write(player.getPlayerId(), "Unable to apply effect.\r\n");
-            }
-        }
-    }
-
-    public static void incrementUses(Item item) {
-        item.setNumberOfUses(item.getNumberOfUses() + 1);
-    }
-}
-
diff --git a/src/main/java/com/comandante/creeper/Items/Loot.java b/src/main/java/com/comandante/creeper/Items/Loot.java
index c45ea8e9986b819519eb1579bc4b98e699d7808d..82e672a056f38a7621abfedc20bf3d02c65093da 100644
--- a/src/main/java/com/comandante/creeper/Items/Loot.java
+++ b/src/main/java/com/comandante/creeper/Items/Loot.java
@@ -1,5 +1,8 @@
 package com.comandante.creeper.Items;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 import java.io.Serializable;
 import java.util.Set;
 
@@ -9,7 +12,8 @@ public class Loot implements Serializable {
     private final long lootGoldMax;
     private final long lootGoldMin;
 
-    public Loot(long lootGoldMin, long lootGoldMax, Set<ItemType> items) {
+    @JsonCreator
+    public Loot(@JsonProperty("lootGoldMin") long lootGoldMin, @JsonProperty("lootGoldMax") long lootGoldMax, @JsonProperty("items") Set<ItemType> items) {
         this.items = items;
         this.lootGoldMax = lootGoldMax;
         this.lootGoldMin = lootGoldMin;
@@ -26,4 +30,5 @@ public class Loot implements Serializable {
     public long getLootGoldMin() {
         return lootGoldMin;
     }
+
 }
diff --git a/src/main/java/com/comandante/creeper/Items/Rarity.java b/src/main/java/com/comandante/creeper/Items/Rarity.java
index 1f2c737f24457e923c6f1ffbba1dd9238fe617d7..e96b38d20ad1ae9489aa1161895f45b09e324179 100644
--- a/src/main/java/com/comandante/creeper/Items/Rarity.java
+++ b/src/main/java/com/comandante/creeper/Items/Rarity.java
@@ -3,11 +3,12 @@ package com.comandante.creeper.Items;
 
 public enum Rarity {
 
-    BASIC("basic", 100.0),
-    UNCOMMON("uncommon", 17.0),
-    RARE("rare", 9.0),
-    LEGENDARY("legendary", 2.0),
-    EXOTIC("exotic", .05);
+    OFTEN("often", 40),
+    BASIC("basic", 15.0),
+    UNCOMMON("uncommon", 7),
+    RARE("rare", 3),
+    LEGENDARY("legendary", 1),
+    EXOTIC("exotic", .5);
 
     private final String rarityTypeName;
     private final double percentToLoot;
diff --git a/src/main/java/com/comandante/creeper/Items/use/DefaultApplyStatsAction.java b/src/main/java/com/comandante/creeper/Items/use/DefaultApplyStatsAction.java
index 9aff2d23af35af57dadf72221e5d0eba2e8e22b8..c92eddea35486b4d67540f97899c3ff53dba0dbe 100644
--- a/src/main/java/com/comandante/creeper/Items/use/DefaultApplyStatsAction.java
+++ b/src/main/java/com/comandante/creeper/Items/use/DefaultApplyStatsAction.java
@@ -1,13 +1,14 @@
 package com.comandante.creeper.Items.use;
 
-import com.codahale.metrics.MetricRegistry;
-import com.comandante.creeper.Items.*;
-import com.comandante.creeper.Main;
+import com.comandante.creeper.Items.Item;
+import com.comandante.creeper.Items.ItemType;
+import com.comandante.creeper.Items.ItemUseAction;
+import com.comandante.creeper.Items.ItemUseHandler;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
-import com.comandante.creeper.server.Color;
 import com.comandante.creeper.spells.Effect;
 import com.comandante.creeper.stat.Stats;
+import org.apache.log4j.Logger;
 
 import java.util.Set;
 
@@ -16,6 +17,7 @@ public class DefaultApplyStatsAction implements ItemUseAction {
     private final Integer itemTypeId;
     private final Stats stats;
     private final Set<Effect> effectSet;
+    private static final Logger log = Logger.getLogger(DefaultApplyStatsAction.class);
 
     public DefaultApplyStatsAction(ItemType itemType, Stats stats, Set<Effect> effects) {
         this.itemTypeId = itemType.getItemTypeCode();
@@ -41,12 +43,12 @@ public class DefaultApplyStatsAction implements ItemUseAction {
         }
         player.addMana(stats.getCurrentMana());
         player.updatePlayerHealth(stats.getCurrentHealth(), null);
-        ItemUseRegistry.processEffects(gameManager, player, effectSet);
+        processEffects(gameManager, player, effectSet);
     }
 
     @Override
     public void postExecuteAction(GameManager gameManager, Player player, Item item) {
-        ItemUseRegistry.incrementUses(item);
+        ItemUseHandler.incrementUses(item);
         if (ItemType.itemTypeFromCode(item.getItemTypeId()).isDisposable()) {
             if (item.getNumberOfUses() < ItemType.itemTypeFromCode(item.getItemTypeId()).getMaxUses()) {
                 gameManager.getEntityManager().saveItem(item);
@@ -61,4 +63,27 @@ public class DefaultApplyStatsAction implements ItemUseAction {
     public Set<Effect> getEffects() {
         return effectSet;
     }
+
+    public static void processEffects(GameManager gameManager, Player player, Set<Effect> effects) {
+        if (effects == null) {
+            return;
+        }
+        for (Effect effect : effects) {
+            Effect nEffect = new Effect(effect);
+            nEffect.setPlayerId(player.getPlayerId());
+            gameManager.getEntityManager().saveEffect(nEffect);
+            boolean effectResult = player.addEffect(nEffect.getEntityId());
+            if (effect.getDurationStats() != null) {
+                if (effect.getDurationStats().getCurrentHealth() < 0) {
+                    log.error("ERROR! Someone added an effect with a health modifier which won't work for various reasons.");
+                    continue;
+                }
+            }
+            if (effectResult) {
+                gameManager.getChannelUtils().write(player.getPlayerId(), "You feel " + effect.getEffectName() + "\r\n");
+            } else {
+                gameManager.getChannelUtils().write(player.getPlayerId(), "Unable to apply effect.\r\n");
+            }
+        }
+    }
 }
diff --git a/src/main/java/com/comandante/creeper/Items/use/DirtyBombUseAction.java b/src/main/java/com/comandante/creeper/Items/use/DirtyBombUseAction.java
index 6a43cb5386689cc525d9bc25344ee54dc7126f2d..e291a97940ea3409f38e622db3818d341f986f83 100644
--- a/src/main/java/com/comandante/creeper/Items/use/DirtyBombUseAction.java
+++ b/src/main/java/com/comandante/creeper/Items/use/DirtyBombUseAction.java
@@ -3,11 +3,10 @@ package com.comandante.creeper.Items.use;
 import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.Items.ItemType;
 import com.comandante.creeper.Items.ItemUseAction;
-import com.comandante.creeper.Items.ItemUseRegistry;
+import com.comandante.creeper.Items.ItemUseHandler;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.npc.NpcStatsChangeBuilder;
-import com.comandante.creeper.player.EquipmentSlotType;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.spells.Effect;
@@ -17,7 +16,6 @@ import com.comandante.creeper.world.Room;
 import java.text.NumberFormat;
 import java.util.Arrays;
 import java.util.Locale;
-import java.util.Objects;
 import java.util.Set;
 
 public class DirtyBombUseAction implements ItemUseAction {
@@ -65,7 +63,7 @@ public class DirtyBombUseAction implements ItemUseAction {
 
     @Override
     public void postExecuteAction(GameManager gameManager, Player player, Item item) {
-        ItemUseRegistry.incrementUses(item);
+        ItemUseHandler.incrementUses(item);
         if (ItemType.itemTypeFromCode(item.getItemTypeId()).isDisposable()) {
             if (item.getNumberOfUses() < ItemType.itemTypeFromCode(item.getItemTypeId()).getMaxUses()) {
                 gameManager.getEntityManager().saveItem(item);
@@ -82,7 +80,7 @@ public class DirtyBombUseAction implements ItemUseAction {
     }
 
     private boolean allRadSuit(Player player) {
-        if (player.getSlotItem(EquipmentSlotType.CHEST) == null || !Objects.equals(player.getSlotItem(EquipmentSlotType.CHEST).getItemTypeId(), ItemType.RADSUIT_CHESTPLATE.getItemTypeCode())) {
+ /*       if (player.getSlotItem(EquipmentSlotType.CHEST) == null || !Objects.equals(player.getSlotItem(EquipmentSlotType.CHEST).getItemTypeId(), ItemType.RADSUIT_CHESTPLATE.getItemTypeCode())) {
             return false;
         }
         if (player.getSlotItem(EquipmentSlotType.LEGS)  == null || !Objects.equals(player.getSlotItem(EquipmentSlotType.LEGS).getItemTypeId(), ItemType.RADSUIT_LEGGINGS.getItemTypeCode())) {
@@ -96,7 +94,7 @@ public class DirtyBombUseAction implements ItemUseAction {
         }
         if (player.getSlotItem(EquipmentSlotType.FEET) == null || !Objects.equals(player.getSlotItem(EquipmentSlotType.FEET).getItemTypeId(), ItemType.RADSUIT_BOOTS.getItemTypeCode())) {
             return false;
-        }
+        }*/
         return true;
 
     }
diff --git a/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java b/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java
new file mode 100644
index 0000000000000000000000000000000000000000..bf40f416630d6ed4d242f8031502c0160d1b78a4
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java
@@ -0,0 +1,51 @@
+package com.comandante.creeper.Items.use;
+
+import com.comandante.creeper.Items.Item;
+import com.comandante.creeper.Items.ItemType;
+import com.comandante.creeper.Items.ItemUseAction;
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.player.Player;
+import com.comandante.creeper.spells.Effect;
+import com.comandante.creeper.spells.LightningSpell;
+
+import java.util.Set;
+
+public class LightningSpellBookUseAction implements ItemUseAction {
+
+    private final ItemType itemType;
+
+    public LightningSpellBookUseAction(ItemType itemType) {
+        this.itemType = itemType;
+    }
+
+    private Boolean dontDelete = Boolean.FALSE;
+
+    @Override
+    public Integer getItemTypeId() {
+        return itemType.getItemTypeCode();
+    }
+
+    @Override
+    public void executeAction(GameManager gameManager, Player player, Item item) {
+        if (player.getLearnedSpells().contains(LightningSpell.NAME)) {
+            gameManager.getChannelUtils().write(player.getPlayerId(), "You already know how to use " + LightningSpell.NAME);
+            dontDelete = true;
+            return;
+        }
+        gameManager.writeToPlayerCurrentRoom(player.getPlayerId(), player.getPlayerName() + " reads a leatherbound aging spell book and gains knowledge about lightning spells.");
+        player.addLearnedSpellByName(LightningSpell.NAME);
+    }
+
+    @Override
+    public void postExecuteAction(GameManager gameManager, Player player, Item item) {
+        if (!dontDelete) {
+            player.removeInventoryId(item.getItemId());
+            gameManager.getEntityManager().removeItem(item);
+        }
+    }
+
+    @Override
+    public Set<Effect> getEffects() {
+        return null;
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/Items/use/ResetAllEffectsUseAction.java b/src/main/java/com/comandante/creeper/Items/use/ResetAllEffectsUseAction.java
index eb610a27f89f656a116d844dbe3219c324f970aa..bae77982e6a219e0a298dd44c76033b94bc41876 100644
--- a/src/main/java/com/comandante/creeper/Items/use/ResetAllEffectsUseAction.java
+++ b/src/main/java/com/comandante/creeper/Items/use/ResetAllEffectsUseAction.java
@@ -3,7 +3,7 @@ package com.comandante.creeper.Items.use;
 import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.Items.ItemType;
 import com.comandante.creeper.Items.ItemUseAction;
-import com.comandante.creeper.Items.ItemUseRegistry;
+import com.comandante.creeper.Items.ItemUseHandler;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.spells.Effect;
@@ -32,7 +32,7 @@ public class ResetAllEffectsUseAction implements ItemUseAction {
 
     @Override
     public void postExecuteAction(GameManager gameManager, Player player, Item item) {
-        ItemUseRegistry.incrementUses(item);
+        ItemUseHandler.incrementUses(item);
         if (ItemType.itemTypeFromCode(item.getItemTypeId()).isDisposable()) {
             if (item.getNumberOfUses() < ItemType.itemTypeFromCode(item.getItemTypeId()).getMaxUses()) {
                 gameManager.getEntityManager().saveItem(item);
diff --git a/src/main/java/com/comandante/creeper/Main.java b/src/main/java/com/comandante/creeper/Main.java
index fb7e1ef2b1c39a8ddeeb9d79971baf272566f2de..5f720a606f2d883c33cbbd07f3ede095edf525fe 100644
--- a/src/main/java/com/comandante/creeper/Main.java
+++ b/src/main/java/com/comandante/creeper/Main.java
@@ -5,11 +5,10 @@ import com.codahale.metrics.MetricFilter;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.graphite.GraphiteReporter;
 import com.codahale.metrics.graphite.PickledGraphite;
-import com.comandante.creeper.Items.ItemUseRegistry;
 import com.comandante.creeper.entity.EntityManager;
-import com.comandante.creeper.player.PlayerManagementManager;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.managers.SessionManager;
+import com.comandante.creeper.player.PlayerManagementManager;
 import com.comandante.creeper.player.PlayerManager;
 import com.comandante.creeper.server.ChannelUtils;
 import com.comandante.creeper.server.CreeperServer;
@@ -24,14 +23,10 @@ import org.mapdb.DB;
 import org.mapdb.DBMaker;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
-import java.util.jar.JarInputStream;
-import java.util.jar.Manifest;
 
 public class Main {
 
@@ -119,9 +114,6 @@ public class Main {
         startUpMessage("Generating map data.");
         mapsManager.generateAllMaps();
 
-        startUpMessage("Configuring Item Use Registry");
-        ItemUseRegistry.configure();
-
         startUpMessage("Configuring default inventorySize limits");
         BackportCommands.configureDefaultInventorySize(entityManager, gameManager);
 
diff --git a/src/main/java/com/comandante/creeper/SingleThreadedCreeperEventProcessor.java b/src/main/java/com/comandante/creeper/SingleThreadedCreeperEventProcessor.java
new file mode 100644
index 0000000000000000000000000000000000000000..7aaca477438f28c1c5d0e4ab5e62a2f993473567
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/SingleThreadedCreeperEventProcessor.java
@@ -0,0 +1,47 @@
+package com.comandante.creeper;
+
+import com.google.api.client.util.Lists;
+import com.google.common.util.concurrent.AbstractScheduledService;
+import org.apache.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class SingleThreadedCreeperEventProcessor extends AbstractScheduledService {
+
+    private final ArrayBlockingQueue<CreeperEvent> creeperEventQueue;
+    private static final Logger log = Logger.getLogger(SingleThreadedCreeperEventProcessor.class);
+
+    public SingleThreadedCreeperEventProcessor(ArrayBlockingQueue<CreeperEvent> creeperEventQueue) {
+        this.creeperEventQueue = creeperEventQueue;
+    }
+
+    @Override
+    protected void runOneIteration() throws Exception {
+        ArrayList<CreeperEvent> events = Lists.newArrayList();
+        creeperEventQueue.drainTo(events);
+        events.forEach(this::safeRun);
+    }
+
+    public void addEvent(CreeperEvent event) {
+        try {
+            creeperEventQueue.put(event);
+        } catch (InterruptedException ex) {
+            log.error("Problem adding event.", ex);
+        }
+    }
+
+    private void safeRun(final CreeperEvent e) {
+        try {
+            e.run();
+        } catch (Exception ex) {
+            log.error("Problem executing event.", ex);
+        }
+    }
+
+    @Override
+    protected Scheduler scheduler() {
+        return Scheduler.newFixedDelaySchedule(0, 50, TimeUnit.MILLISECONDS);
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/blackjack/BlackJack.java b/src/main/java/com/comandante/creeper/blackjack/BlackJack.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ed25cee638d520ddd17ee05ebb9dc0276f7f7f6
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/blackjack/BlackJack.java
@@ -0,0 +1,73 @@
+package com.comandante.creeper.blackjack;
+
+
+import com.comandante.creeper.CreeperUtils;
+import com.google.common.collect.Lists;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class BlackJack {
+
+    public static class Card {
+
+        public final Deck.Type type;
+        public final Deck.Suit suit;
+
+        public Card(Deck.Suit suit, Deck.Type type) {
+            this.type = type;
+            this.suit = suit;
+        }
+    }
+
+    public static String templateCard =
+            "┌─────────┐\n" +
+                    "│{0}        │\n" +
+                    "│         │\n" +
+                    "│         │\n" +
+                    "│   {1}     │\n" +
+                    "│         │\n" +
+                    "│         │\n" +
+                    "│       {0} │\n" +
+                    "└─────────┘\n";
+
+    public static String getAsciiPlayingCardHand(List<Card> card) {
+        List<String> asciiCards = card.stream().map(BlackJack::getAsciiPlayingCard).collect(Collectors.toList());
+        return CreeperUtils.printStringsNextToEachOther(asciiCards, "");
+    }
+
+
+    public static String getAsciiPlayingCard(Card card) {
+        String rawTemplate = templateCard;
+        if (card.type.textRepresentation.length() == 2) {
+            StringBuilder sb = new StringBuilder();
+            ArrayList<String> strings = Lists.newArrayList(templateCard.split("[\\r\\n]+"));
+            strings.stream().map(s -> {
+                if (s.contains("{0}")) {
+                    return s.replace("{0} ", "{0}");
+                }
+                return s;
+            }).forEach((str) -> sb.append(str).append("\r\n"));
+            rawTemplate = sb.toString();
+        }
+
+        MessageFormat messageFormat = new MessageFormat(rawTemplate);
+        return messageFormat.format(Lists.newArrayList(card.type.textRepresentation, card.suit.textRepresentation).toArray());
+    }
+
+    public static void main(String[] args) {
+
+        String test = "   │7        │   ";
+        String s = CreeperUtils.trimTrailingBlanks(test);
+        System.out.println(s);
+
+        Deck deck = new Deck();
+        deck.shuffle();
+        List<Card> cards = Lists.newArrayList(deck.next(), deck.next(), deck.next(), deck.next());
+        String asciiPlayingCardHand = getAsciiPlayingCardHand(cards);
+        System.out.println(asciiPlayingCardHand);
+    }
+
+}
diff --git a/src/main/java/com/comandante/creeper/blackjack/Deck.java b/src/main/java/com/comandante/creeper/blackjack/Deck.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ebc0a5d1f668bb06a907a6e9c5e97eda374b834
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/blackjack/Deck.java
@@ -0,0 +1,104 @@
+package com.comandante.creeper.blackjack;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+
+public class Deck implements Iterator<BlackJack.Card> {
+
+    enum Type {
+        ACE(1, "A"),
+        KING(10, "K"),
+        QUEEN(10, "Q"),
+        JACK(10, "J"),
+        TWO(2),
+        THREE(3),
+        FOUR(4),
+        FIVE(5),
+        SIX(6),
+        SEVEN(7),
+        EIGHT(8),
+        NINE(9),
+        TEN(10);
+
+
+        public final int value;
+        public final String textRepresentation;
+
+        Type(int value, String textRepresentation) {
+            this.value = value;
+            this.textRepresentation = textRepresentation;
+        }
+
+
+        Type(int value) {
+            this.value = value;
+            this.textRepresentation = String.valueOf(value);
+        }
+    }
+
+    enum Suit {
+        SPADES("â™ "),
+        HEARTS("♥"),
+        DIAMONDS("♦"),
+        CLUBS("♣");
+
+        public final String textRepresentation;
+
+        Suit(String textRepresentation) {
+            this.textRepresentation = textRepresentation;
+        }
+
+        public String getName() {
+            return StringUtils.capitalize(this.name().toLowerCase());
+        }
+    }
+
+
+    private List<BlackJack.Card> deckCards = Lists.newArrayList();
+    private Iterator<BlackJack.Card> delegate = deckCards.iterator();
+
+    public Deck() {
+        Arrays.stream(Deck.Suit.values())
+                .forEach(suit ->
+                        Arrays.stream(Deck.Type.values())
+                                .forEach(type ->
+                                        deckCards.add(new BlackJack.Card(suit, type))));
+    }
+
+    public void shuffle() {
+        Collections.shuffle(deckCards);
+    }
+
+    @Override
+    public boolean hasNext() {
+        return delegate.hasNext();
+    }
+
+    @Override
+    public BlackJack.Card next() {
+        BlackJack.Card next = deckCards.iterator().next();
+        ArrayList<BlackJack.Card> copy = Lists.newArrayList(deckCards);
+        copy.remove(next);
+        deckCards = copy;
+        delegate = copy.iterator();
+        return next;
+    }
+
+    public BlackJack.Card deal() {
+        return next();
+    }
+
+
+    public void addCard(BlackJack.Card card) {
+        ArrayList<BlackJack.Card> copy = Lists.newArrayList(deckCards);
+        copy.add(card);
+        deckCards = copy;
+        delegate = copy.iterator();
+    }
+
+    public int size() {
+        return deckCards.size();
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/bot/BotCommandFactory.java b/src/main/java/com/comandante/creeper/bot/BotCommandFactory.java
index 4d7cc209527ab14eb78dcf545015d693acccdb3e..b6eb9077fb62a23456a522d667d1ec16384fe58c 100644
--- a/src/main/java/com/comandante/creeper/bot/BotCommandFactory.java
+++ b/src/main/java/com/comandante/creeper/bot/BotCommandFactory.java
@@ -3,7 +3,10 @@ package com.comandante.creeper.bot;
 import com.comandante.creeper.bot.commands.*;
 import com.google.common.collect.Maps;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 
 public class BotCommandFactory {
 
@@ -16,6 +19,8 @@ public class BotCommandFactory {
         addCommand(new DictionaryBotCommand(botCommandManager));
         addCommand(new ImdbBotCommand(botCommandManager));
         addCommand(new ForecastCommand(botCommandManager));
+        addCommand(new RandomRoomDescriptionCommand(botCommandManager));
+        addCommand(new CardsCommand(botCommandManager));
     }
 
     public BotCommand getCommand(String originalFullCmd) {
diff --git a/src/main/java/com/comandante/creeper/bot/commands/CardsCommand.java b/src/main/java/com/comandante/creeper/bot/commands/CardsCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..50ad41abb983ab1d1f17bbf54a42396b3d914c92
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/bot/commands/CardsCommand.java
@@ -0,0 +1,32 @@
+package com.comandante.creeper.bot.commands;
+
+import com.comandante.creeper.blackjack.BlackJack;
+import com.comandante.creeper.blackjack.Deck;
+import com.comandante.creeper.bot.BotCommandManager;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import java.util.List;
+import java.util.Set;
+
+public class CardsCommand extends BotCommand {
+
+    static Set<String> triggers = Sets.newHashSet("cards");
+    static String helpUsage = "cards";
+    static String helpDescription = "Some random cards.";
+
+    public CardsCommand(BotCommandManager botCommandManager) {
+        super(botCommandManager, triggers, helpUsage, helpDescription);
+    }
+
+    @Override
+    public List<String> process() {
+        Deck deck = new Deck();
+        deck.shuffle();
+        List<BlackJack.Card> cards = com.google.common.collect.Lists.newArrayList(deck.next(), deck.next(), deck.next(), deck.next(), deck.deal());
+        String asciiPlayingCardHand = BlackJack.getAsciiPlayingCardHand(cards);
+        List<String> resp = Lists.newArrayList();
+        resp.addAll(Lists.newArrayList(asciiPlayingCardHand.split("[\\r\\n]+")));
+        return resp;
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/bot/commands/RandomRoomDescriptionCommand.java b/src/main/java/com/comandante/creeper/bot/commands/RandomRoomDescriptionCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c007dd7b425d3bc3fe9ba0096058dd93cecd6de
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/bot/commands/RandomRoomDescriptionCommand.java
@@ -0,0 +1,45 @@
+package com.comandante.creeper.bot.commands;
+
+
+import com.comandante.creeper.bot.BotCommandManager;
+import com.comandante.creeper.world.Coords;
+import com.comandante.creeper.world.Room;
+import com.google.api.client.util.Lists;
+import com.google.common.collect.Sets;
+
+import java.util.*;
+
+public class RandomRoomDescriptionCommand extends BotCommand {
+
+    static Set<String> triggers = Sets.newHashSet("blazecraft");
+    static String helpUsage = "blazecraft";
+    static String helpDescription = "A random room description, courtesy of BLAZECRAFT";
+    private final Random random = new Random();
+
+    public RandomRoomDescriptionCommand(BotCommandManager botCommandManager) {
+        super(botCommandManager, triggers, helpUsage, helpDescription);
+    }
+
+    @Override
+    public List<String> process() {
+        Map<Integer, Room> getrooms = botCommandManager.getGameManager().getRoomManager().getrooms();
+        int size = getrooms.size();
+        int randomRoomNumber = randInt(1, size);
+        Room randomRoom = getrooms.get(randomRoomNumber);
+        ArrayList<String> output = Lists.newArrayList();
+        output.add(randomRoom.getRoomTitle());
+        output.add(" ");
+        output.add(randomRoom.getRoomDescription());
+        /*String mapString = botCommandManager.getGameManager().getMapsManager().drawMap(randomRoom.getRoomId(), new Coords(5, 5));
+        String[] split = mapString.split("\\r?\\n");
+        for (String s: split) {
+            output.add(s);
+        }*/
+        return output;
+    }
+
+    private int randInt(int min, int max) {
+        int randomNum = random.nextInt((max - min) + 1) + min;
+        return randomNum;
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/BackCommand.java b/src/main/java/com/comandante/creeper/command/BackCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..e7fa4d66209a28dc4df4fd1533b7b557c1b10e74
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/BackCommand.java
@@ -0,0 +1,32 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.player.PlayerMovement;
+import com.comandante.creeper.world.Room;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class BackCommand extends Command {
+
+    final static List<String> validTriggers = Arrays.asList("back", "b");
+    final static String description = "Return to where you came from.";
+    final static String correctUsage = "back";
+
+    public BackCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+            Room returnRoom = player.getPreviousRoom();
+            player.removeActiveAlertStatus();
+            PlayerMovement playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), returnRoom.getRoomId(), "fleed to where they came from.", "up");
+            player.movePlayer(playerMovement);
+        });
+    }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/CardsCommand.java b/src/main/java/com/comandante/creeper/command/CardsCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..c155559448f3a702af3f5ed1bc8df0eed83fac01
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/CardsCommand.java
@@ -0,0 +1,34 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.blackjack.BlackJack;
+import com.comandante.creeper.blackjack.Deck;
+import com.comandante.creeper.managers.GameManager;
+import com.google.common.collect.Lists;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CardsCommand extends Command {
+
+    final static List<String> validTriggers = Arrays.asList("cards");
+    final static String description = "Display Random Cards";
+    final static String correctUsage = "cards";
+
+    public CardsCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+            Deck deck = new Deck();
+            deck.shuffle();
+            List<BlackJack.Card> cards = Lists.newArrayList(deck.next(), deck.next(), deck.next(), deck.next(), deck.deal());
+            String asciiPlayingCardHand = BlackJack.getAsciiPlayingCardHand(cards);
+            write(asciiPlayingCardHand + "\r\n");
+        });
+    }
+
+}
diff --git a/src/main/java/com/comandante/creeper/command/CastCommand.java b/src/main/java/com/comandante/creeper/command/CastCommand.java
index c8236f38cf651d5f7c95bdbba3af87907e73be5a..ae7e281d4090f26e90bf111002dc3edb6841456a 100644
--- a/src/main/java/com/comandante/creeper/command/CastCommand.java
+++ b/src/main/java/com/comandante/creeper/command/CastCommand.java
@@ -6,7 +6,7 @@ import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.player.CoolDownType;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.spells.Spell;
-import com.comandante.creeper.spells.SpellRegistry;
+import com.comandante.creeper.spells.SpellTriggerRegistry;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
@@ -27,8 +27,7 @@ public class CastCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        try {
-            configure(e);
+        execCommand(ctx, e, () -> {
             if (player.getCurrentHealth() <= 0) {
                 write("You have no health and as such you can not attack.");
                 return;
@@ -42,8 +41,8 @@ public class CastCommand extends Command {
                 return;
             }
             String desiredSpellName = originalMessageParts.get(1);
-            Spell spell = SpellRegistry.getSpell(desiredSpellName);
-            if (spell == null) {
+            Spell spell = SpellTriggerRegistry.getSpell(desiredSpellName);
+            if (spell == null || !player.doesHaveSpellLearned(spell.getSpellName())) {
                 write("No spell found with the name: " + desiredSpellName + "\r\n");
                 return;
             }
@@ -81,8 +80,6 @@ public class CastCommand extends Command {
                     return;
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/ColorsCommand.java b/src/main/java/com/comandante/creeper/command/ColorsCommand.java
index 190650f53318d244cff9d7f0bad2b0b5d3ded952..576e3ef2eb53aacbe8af004c4ddec0581f15c23d 100644
--- a/src/main/java/com/comandante/creeper/command/ColorsCommand.java
+++ b/src/main/java/com/comandante/creeper/command/ColorsCommand.java
@@ -1,10 +1,8 @@
 package com.comandante.creeper.command;
 
 
-import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.server.Color;
-import com.google.common.base.Joiner;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -23,27 +21,24 @@ public class ColorsCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            write ("BLACK: " + Color.BLACK + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("BLUE: " + Color.BLUE + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("CYAN: " + Color.CYAN + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("GREEN: " + Color.GREEN + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("MAGENTA: " + Color.MAGENTA + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("RED: " + Color.RED + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("WHITE: " + Color.WHITE + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("YELLOW: " + Color.YELLOW + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("\r\n\r\nBOLD COLORS\r\n");
-            write ("BLACK: " + Color.BOLD_ON + Color.BLACK + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("BLUE: "  + Color.BOLD_ON + Color.BLUE + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("CYAN: "  + Color.BOLD_ON + Color.CYAN + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("GREEN: "  + Color.BOLD_ON + Color.GREEN + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("MAGENTA: "  + Color.BOLD_ON + Color.MAGENTA + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("RED: "  + Color.BOLD_ON  + Color.RED + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("WHITE: "  + Color.BOLD_ON + Color.WHITE + "This is an example of the color." + Color.RESET + "\r\n");
-            write ("YELLOW: "  + Color.BOLD_ON + Color.YELLOW + "This is an example of the color." + Color.RESET + "\r\n");
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        execCommand(ctx, e, () -> {
+            write("BLACK: " + Color.BLACK + "This is an example of the color." + Color.RESET + "\r\n");
+            write("BLUE: " + Color.BLUE + "This is an example of the color." + Color.RESET + "\r\n");
+            write("CYAN: " + Color.CYAN + "This is an example of the color." + Color.RESET + "\r\n");
+            write("GREEN: " + Color.GREEN + "This is an example of the color." + Color.RESET + "\r\n");
+            write("MAGENTA: " + Color.MAGENTA + "This is an example of the color." + Color.RESET + "\r\n");
+            write("RED: " + Color.RED + "This is an example of the color." + Color.RESET + "\r\n");
+            write("WHITE: " + Color.WHITE + "This is an example of the color." + Color.RESET + "\r\n");
+            write("YELLOW: " + Color.YELLOW + "This is an example of the color." + Color.RESET + "\r\n");
+            write("\r\n\r\nBOLD COLORS\r\n");
+            write("BLACK: " + Color.BOLD_ON + Color.BLACK + "This is an example of the color." + Color.RESET + "\r\n");
+            write("BLUE: " + Color.BOLD_ON + Color.BLUE + "This is an example of the color." + Color.RESET + "\r\n");
+            write("CYAN: " + Color.BOLD_ON + Color.CYAN + "This is an example of the color." + Color.RESET + "\r\n");
+            write("GREEN: " + Color.BOLD_ON + Color.GREEN + "This is an example of the color." + Color.RESET + "\r\n");
+            write("MAGENTA: " + Color.BOLD_ON + Color.MAGENTA + "This is an example of the color." + Color.RESET + "\r\n");
+            write("RED: " + Color.BOLD_ON + Color.RED + "This is an example of the color." + Color.RESET + "\r\n");
+            write("WHITE: " + Color.BOLD_ON + Color.WHITE + "This is an example of the color." + Color.RESET + "\r\n");
+            write("YELLOW: " + Color.BOLD_ON + Color.YELLOW + "This is an example of the color." + Color.RESET + "\r\n");
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/Command.java b/src/main/java/com/comandante/creeper/command/Command.java
index 43a1901549b7ada1240dd9dada21e7281266a9b4..0489843848e20e78762482c2b54e4d9c118ff284 100644
--- a/src/main/java/com/comandante/creeper/command/Command.java
+++ b/src/main/java/com/comandante/creeper/command/Command.java
@@ -7,12 +7,15 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerManager;
 import com.comandante.creeper.player.PlayerRole;
-import com.comandante.creeper.server.ChannelUtils;
+import com.comandante.creeper.server.ChannelCommunicationUtils;
 import com.comandante.creeper.server.CreeperSession;
 import com.comandante.creeper.world.*;
 import com.google.common.collect.Sets;
 import org.apache.log4j.Logger;
-import org.jboss.netty.channel.*;
+import org.jboss.netty.channel.ChannelEvent;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
@@ -22,6 +25,7 @@ import java.util.Set;
 
 public abstract class Command extends SimpleChannelUpstreamHandler {
 
+    public static final Logger log = Logger.getLogger(Command.class);
     public final List<String> validTriggers;
     public final String description;
     public final Set<PlayerRole> roles;
@@ -31,7 +35,7 @@ public abstract class Command extends SimpleChannelUpstreamHandler {
     public final EntityManager entityManager;
     public final RoomManager roomManager;
     public final PlayerManager playerManager;
-    public final ChannelUtils channelUtils;
+    public final ChannelCommunicationUtils channelUtils;
     public final LootManager lootManager;
     public final String correctUsage;
     public CreeperSession creeperSession;
@@ -42,7 +46,7 @@ public abstract class Command extends SimpleChannelUpstreamHandler {
     public Coords currentRoomCoords;
     public List<String> originalMessageParts;
     public WorldExporter worldExporter;
-    public static final Logger log = Logger.getLogger(Command.class);
+    public String rootCommand;
 
     protected Command(GameManager gameManager, List<String> validTriggers, String description, String correctUsage) {
         this(gameManager, validTriggers, description, correctUsage, Sets.<PlayerRole>newHashSet());
@@ -64,49 +68,89 @@ public abstract class Command extends SimpleChannelUpstreamHandler {
         this.roles = roles;
     }
 
-    public void configure(MessageEvent e) {
-        this.creeperSession = extractCreeperSession(e.getChannel());
-        this.player = playerManager.getPlayer(extractPlayerId(creeperSession));
+    @Override
+    public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
+        try {
+            if (e instanceof MessageEvent) {
+                init((MessageEvent) e);
+            }
+        } finally {
+            super.handleUpstream(ctx, e);
+        }
+    }
+
+    private void init(MessageEvent e) {
+        this.creeperSession = (CreeperSession) e.getChannel().getAttachment();;
+        this.originalMessageParts = getOriginalMessageParts(e);
+        this.rootCommand = getRootCommand(e);
+        this.player = playerManager.getPlayer(Main.createPlayerId(creeperSession.getUsername().get()));
         this.playerId = player.getPlayerId();
         this.currentRoom = gameManager.getRoomManager().getPlayerCurrentRoom(player).get();
         this.mapMatrix = mapsManager.getFloorMatrixMaps().get(currentRoom.getFloorId());
         this.currentRoomCoords = mapMatrix.getCoords(currentRoom.getRoomId());
-        this.originalMessageParts = getOriginalMessageParts(e);
     }
 
-    @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        try {
-            CreeperSession creeperSession = extractCreeperSession(e.getChannel());
-            e.getChannel().getPipeline().remove(ctx.getHandler());
-            if (creeperSession.getGrabMerchant().isPresent()) {
-                return;
+    private List<String> getOriginalMessageParts(MessageEvent e) {
+        String origMessage = (String) e.getMessage();
+        return new ArrayList<>(Arrays.asList(origMessage.split(" ")));
+    }
+
+    private String getRootCommand(MessageEvent e) {
+        String origMessage = (String) e.getMessage();
+        return origMessage.split(" ")[0].toLowerCase();
+    }
+
+    public void execCommandThreadSafe(ChannelHandlerContext ctx, MessageEvent e, Class c, CommandRunnable commandRunnable) throws Exception {
+        synchronized (c) {
+            try {
+                commandRunnable.run();
+            } catch (Exception ex) {
+                log.error("Problem running command.", ex);
+            } finally {
+                removeCurrentHandlerAndWritePrompt(ctx, e);
+                ctx.sendUpstream(e);
             }
-            String playerId = extractPlayerId(creeperSession);
-            String prompt = gameManager.buildPrompt(playerId);
-            gameManager.getChannelUtils().write(playerId, prompt, true);
-        } finally {
-            super.messageReceived(ctx, e);
         }
     }
 
-    public CreeperSession extractCreeperSession(Channel channel) {
-        return (CreeperSession) channel.getAttachment();
+    private void removeCurrentHandlerAndWritePrompt(ChannelHandlerContext ctx, MessageEvent e) {
+        removeCurrentHandlerAndWritePrompt(ctx, e, true);
     }
 
+    public void removeCurrentHandlerAndWritePrompt(ChannelHandlerContext ctx, MessageEvent e, boolean newLine) {
+        e.getChannel().getPipeline().remove(ctx.getHandler());
+        if (creeperSession.getGrabMerchant().isPresent()) {
+            return;
+        }
+        gameManager.getChannelUtils().write(playerId, getPrompt(), newLine);
+    }
 
-    public String extractPlayerId(CreeperSession creeperSession) {
-        return Main.createPlayerId(creeperSession.getUsername().get());
+    public String getPrompt() {
+        return gameManager.buildPrompt(playerId);
     }
 
-    public String getRootCommand(MessageEvent e) {
-        String origMessage = (String) e.getMessage();
-        return origMessage.split(" ")[0].toLowerCase();
+    public void execCommandBackgroundThread(ChannelHandlerContext ctx, MessageEvent e, CommandRunnable commandRunnable) throws Exception {
+        try {
+            new Thread(() -> {
+                try {
+                    commandRunnable.run();
+                } catch (Exception ex) {
+                    log.error("Problem running command.", ex);
+                }
+            }).start();
+        } finally {
+            removeCurrentHandlerAndWritePrompt(ctx, e);
+            ctx.sendUpstream(e);
+        }
     }
 
-    public List<String> getOriginalMessageParts(MessageEvent e) {
-        String origMessage = (String) e.getMessage();
-        return new ArrayList<>(Arrays.asList(origMessage.split(" ")));
+    public void execCommand(ChannelHandlerContext ctx, MessageEvent e, CommandRunnable commandRunnable) throws Exception {
+        try {
+            commandRunnable.run();
+        } finally {
+            removeCurrentHandlerAndWritePrompt(ctx, e);
+            ctx.sendUpstream(e);
+        }
     }
 
     public void write(String msg) {
@@ -121,58 +165,21 @@ public abstract class Command extends SimpleChannelUpstreamHandler {
         gameManager.writeToPlayerCurrentRoom(playerId, msg);
     }
 
-    public void currentRoomLogic() {
+    public void printCurrentRoomInformation() {
         gameManager.currentRoomLogic(playerId);
     }
 
-    public void currentRoomLogic(Room playerCurrentRoom) {
+    public void printCurrentRoomInformation(Room playerCurrentRoom) {
         gameManager.currentRoomLogic(playerId, playerCurrentRoom);
     }
 
-    public String getPrompt() {
-        return gameManager.buildPrompt(playerId);
-    }
-
     public String getDescription() {
         return description;
     }
 
-    public static boolean isInteger(String s) {
-        try {
-            Integer.parseInt(s);
-        } catch(NumberFormatException e) {
-            return false;
-        } catch(NullPointerException e) {
-            return false;
-        }
-        // only got here if we didn't return false
-        return true;
-    }
-
     public Command copy() throws ClassNotFoundException,
             InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
         Class<Command> clazz = (Class<Command>) this.getClass();
         return clazz.getConstructor(GameManager.class).newInstance(gameManager);
     }
-
-    public <T> T createObj(String nameclass) throws ClassNotFoundException,
-            InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
-
-        Class<T> clazz = (Class<T>) Class.forName(nameclass);
-
-        // assumes the target class has a no-args Constructor
-        return clazz.getConstructor(GameManager.class).newInstance(gameManager);
-    }
-
-    public static boolean isLong(String s) {
-        try {
-            Long.parseLong(s);
-        } catch(NumberFormatException e) {
-            return false;
-        } catch(NullPointerException e) {
-            return false;
-        }
-        // only got here if we didn't return false
-        return true;
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/CommandRunnable.java b/src/main/java/com/comandante/creeper/command/CommandRunnable.java
new file mode 100644
index 0000000000000000000000000000000000000000..2389edbe270db49b79869e96932abd3d64a31e62
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/CommandRunnable.java
@@ -0,0 +1,6 @@
+package com.comandante.creeper.command;
+
+
+public interface CommandRunnable {
+    void run() throws java.lang.Exception;
+}
diff --git a/src/main/java/com/comandante/creeper/command/CompareCommand.java b/src/main/java/com/comandante/creeper/command/CompareCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..232eb79dfc44387756ce998250b2ba49089c61e6
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/CompareCommand.java
@@ -0,0 +1,60 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.CreeperUtils;
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.npc.Npc;
+import com.comandante.creeper.player.Levels;
+import com.comandante.creeper.player.Player;
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+public class CompareCommand extends Command {
+
+    final static List<String> validTriggers = Arrays.asList("compare");
+    final static String description = "Compare yourself to another player or npc.";
+    final static String correctUsage = "compare <playerName>||<npc>";
+
+    public CompareCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+            if (originalMessageParts.size() == 1) {
+                printCurrentRoomInformation();
+                return;
+            }
+            originalMessageParts.remove(0);
+            String target = Joiner.on(" ").join(originalMessageParts);
+            String selfLookStrong = player.getLookString();
+            //Players
+            Set<Player> presentPlayers = roomManager.getPresentPlayers(currentRoom);
+            for (Player presentPlayer : presentPlayers) {
+                if (presentPlayer != null && presentPlayer.getPlayerName().equals(target)) {
+                    String targetLookString = presentPlayer.getLookString();
+                    write(CreeperUtils.printStringsNextToEachOther(Lists.newArrayList(selfLookStrong, targetLookString), " | ")+ "\r\n");
+                    if (!presentPlayer.getPlayerId().equals(playerId)) {
+                        channelUtils.write(presentPlayer.getPlayerId(), player.getPlayerName() + " compares themself to you.", true);
+                    }
+                }
+            }
+
+            //NPCS
+            Set<String> npcIds = currentRoom.getNpcIds();
+            for (String npcId : npcIds) {
+                Npc currentNpc = gameManager.getEntityManager().getNpcEntity(npcId);
+                if (currentNpc.getValidTriggers().contains(target)) {
+                    String npcLookString = gameManager.getLookString(currentNpc, Levels.getLevel(gameManager.getStatsModifierFactory().getStatsModifier(player).getExperience()));
+                    write(CreeperUtils.printStringsNextToEachOther(Lists.newArrayList(selfLookStrong, npcLookString)," | ") + "\r\n");
+                }
+            }
+        });
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/CoolDownCommand.java b/src/main/java/com/comandante/creeper/command/CoolDownCommand.java
index 7678339bd00670b9d67a7c1354a20096314514b1..7dace727f1ec9578d14c494e24eecf8f0dc280b0 100644
--- a/src/main/java/com/comandante/creeper/command/CoolDownCommand.java
+++ b/src/main/java/com/comandante/creeper/command/CoolDownCommand.java
@@ -1,7 +1,6 @@
 package com.comandante.creeper.command;
 
 import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.server.Color;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -20,15 +19,13 @@ public class CoolDownCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (player.isActiveCoolDown()) {
                 write(gameManager.renderCoolDownString(player.getCoolDowns()));
             } else {
                 write("No active cooldowns.\r\n");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
+
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/CountdownCommand.java b/src/main/java/com/comandante/creeper/command/CountdownCommand.java
index bf6a26ca1df8d2b86e927f24ae881913205fc93b..155e7190c50db9642547f389fd9ef9312314e232 100644
--- a/src/main/java/com/comandante/creeper/command/CountdownCommand.java
+++ b/src/main/java/com/comandante/creeper/command/CountdownCommand.java
@@ -3,13 +3,15 @@ package com.comandante.creeper.command;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerManager;
-import com.comandante.creeper.server.ChannelUtils;
+import com.comandante.creeper.server.ChannelCommunicationUtils;
 import com.comandante.creeper.server.Color;
 import com.google.common.collect.Lists;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
 import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 
 public class CountdownCommand extends Command {
 
@@ -23,39 +25,29 @@ public class CountdownCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            new Thread(new PrintCountdown(playerManager, channelUtils)).start();
-        } finally {
-            super.messageReceived(ctx, e);
-        }
-    }
-
-    public static class PrintCountdown implements Runnable {
-
-        private PlayerManager playerManager;
-        private ChannelUtils channelUtils;
-
-        public PrintCountdown(PlayerManager playerManager, ChannelUtils channelUtils) {
-            this.playerManager = playerManager;
-            this.channelUtils = channelUtils;
-        }
-
-        @Override
-        public void run() {
-            ArrayList<String> strings = Lists.newArrayList("... ***** COUNTDOWN ***** ...", ".             5             .", ".             4             .", ".             3             .", ".             2             .", ".             1             .", "... *****   SMOKE!  ***** ...");
-            for (String s : strings) {
-                Iterator<Map.Entry<String, Player>> players = playerManager.getPlayers();
-                while (players.hasNext()) {
-                    Map.Entry<String, Player> next = players.next();
-                    channelUtils.write(next.getValue().getPlayerId(), Color.BOLD_ON + Color.GREEN + s + Color.RESET + "\r\n", true);
-                }
+        execCommandBackgroundThread(ctx, e, () -> {
+            ArrayList<String> countDownMessages =
+                    Lists.newArrayList("... ***** COUNTDOWN ***** ...",
+                            ".             5             .",
+                            ".             4             .",
+                            ".             3             .",
+                            ".             2             .",
+                            ".             1             .",
+                            "... *****   SMOKE!  ***** ...");
+
+
+            countDownMessages.forEach(message -> {
+                writeMessageToEveryPlayer(message);
                 try {
                     Thread.sleep(900);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
+                } catch (InterruptedException ex) {
+                    log.error("Problem while printing countdown message", ex);
                 }
-            }
-        }
+            });
+        });
+    }
+
+    private void writeMessageToEveryPlayer(String message) {
+        playerManager.getAllPlayersMap().forEach((playerId1, player1) -> channelUtils.write(playerId1, Color.BOLD_ON + Color.GREEN + message + Color.RESET + "\r\n", true));
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/DelCommand.java b/src/main/java/com/comandante/creeper/command/DelCommand.java
index 6842ac7d2e0d11618cceaf5c112d8c688661d581..ce1c80f23955c982a9bbb9a0efb270862afc69fa 100644
--- a/src/main/java/com/comandante/creeper/command/DelCommand.java
+++ b/src/main/java/com/comandante/creeper/command/DelCommand.java
@@ -2,9 +2,7 @@ package com.comandante.creeper.command;
 
 
 import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.player.PlayerSettings;
 import com.google.api.client.util.Lists;
-import com.google.common.base.Joiner;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -24,9 +22,8 @@ public class DelCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-           if (originalMessageParts.size() <= 1) {
+        execCommand(ctx, e, () -> {
+            if (originalMessageParts.size() <= 1) {
                 write(returnAllSettings());
                 return;
             }
@@ -34,9 +31,7 @@ public class DelCommand extends Command {
             String desiredSettingName = originalMessageParts.get(0);
             player.removePlayerSetting(desiredSettingName);
             write("Setting removed.\r\n");
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 
     private String returnAllSettings() {
diff --git a/src/main/java/com/comandante/creeper/command/DropCommand.java b/src/main/java/com/comandante/creeper/command/DropCommand.java
index 0a06915de2ef3b0a66e42aec37cb05be8189677b..0f90e752defa7c89904950544041ee6c5f6fc68d 100644
--- a/src/main/java/com/comandante/creeper/command/DropCommand.java
+++ b/src/main/java/com/comandante/creeper/command/DropCommand.java
@@ -21,8 +21,7 @@ public class DropCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
                 write("No item specified.");
                 return;
@@ -40,8 +39,6 @@ public class DropCommand extends Command {
                     return;
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/EquipCommand.java b/src/main/java/com/comandante/creeper/command/EquipCommand.java
index f7885d72acf6d935a2798bb7494a0f0d61b93c36..eba3949e713809c3a6a27953fe7388d39ef9893f 100644
--- a/src/main/java/com/comandante/creeper/command/EquipCommand.java
+++ b/src/main/java/com/comandante/creeper/command/EquipCommand.java
@@ -21,8 +21,7 @@ public class EquipCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
                 write("No equipment item specified.");
                 return;
@@ -44,8 +43,6 @@ public class EquipCommand extends Command {
             } else {
                 write("Your inventory is empty.");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/FightKillCommand.java b/src/main/java/com/comandante/creeper/command/FightKillCommand.java
index cff05bbb9ac84bf9c32498b423d4ba2c1b84d197..6abad3319e571df2343078f174c16c2d5d4c5096 100644
--- a/src/main/java/com/comandante/creeper/command/FightKillCommand.java
+++ b/src/main/java/com/comandante/creeper/command/FightKillCommand.java
@@ -23,8 +23,7 @@ public class FightKillCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (player.getCurrentHealth() <= 0) {
                 write("You have no health and as such you can not attack.");
                 return;
@@ -57,8 +56,6 @@ public class FightKillCommand extends Command {
                 }
             }
             write("There's no NPC here to fight by that name.");
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/ForageCommand.java b/src/main/java/com/comandante/creeper/command/ForageCommand.java
index e9a9a4b525fd68f9bf8fbf05bc19d016187f3890..dd05e16e04e380715cc2f029623c6436a464c9e0 100644
--- a/src/main/java/com/comandante/creeper/command/ForageCommand.java
+++ b/src/main/java/com/comandante/creeper/command/ForageCommand.java
@@ -19,11 +19,6 @@ public class ForageCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        try {
-            configure(e);
-            gameManager.getForageManager().getForageForRoom(currentRoom, player);
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        execCommand(ctx, e, () -> gameManager.getForageManager().getForageForRoom(currentRoom, player));
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/GoldCommand.java b/src/main/java/com/comandante/creeper/command/GoldCommand.java
index 605b0c156768db1970f51845aaa3e4017ebbbe7e..a407223dc78b4fe7a44d7c205b24a3c6a09f6b6b 100644
--- a/src/main/java/com/comandante/creeper/command/GoldCommand.java
+++ b/src/main/java/com/comandante/creeper/command/GoldCommand.java
@@ -23,11 +23,6 @@ public class GoldCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-          write("You have " + NumberFormat.getNumberInstance(Locale.US).format(playerManager.getPlayerMetadata(playerId).getGold()) + Color.YELLOW + " gold." + Color.RESET);
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        execCommand(ctx, e, () -> write("You have " + NumberFormat.getNumberInstance(Locale.US).format(playerManager.getPlayerMetadata(playerId).getGold()) + Color.YELLOW + " gold." + Color.RESET));
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/GossipCommand.java b/src/main/java/com/comandante/creeper/command/GossipCommand.java
index ff92e83e368c4aea90350c31554168a49856c1cb..a3e312fc502e929c9128c865bbd41e37a34c8db1 100644
--- a/src/main/java/com/comandante/creeper/command/GossipCommand.java
+++ b/src/main/java/com/comandante/creeper/command/GossipCommand.java
@@ -4,13 +4,13 @@ package com.comandante.creeper.command;
 import com.comandante.creeper.bot.commands.BotCommand;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
-import com.comandante.creeper.server.Color;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
 import java.util.*;
+import java.util.function.BiConsumer;
 
 import static com.comandante.creeper.server.Color.*;
 
@@ -26,8 +26,7 @@ public class GossipCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
                 write("Nothing to gossip about?");
                 return;
@@ -42,21 +41,16 @@ public class GossipCommand extends Command {
             } catch (Exception ex) {
                 log.error("Problem executing bot command from gossip channel!", ex);
             }
-            Iterator<Map.Entry<String, Player>> players = playerManager.getPlayers();
-            String gossipMessage = null;
-            while (players.hasNext()) {
-                final Player next = players.next().getValue();
-                gossipMessage =   WHITE + "[" + RESET + MAGENTA + player.getPlayerName() +  WHITE + "] " + RESET + CYAN + msg + RESET;
-                if (next.getPlayerId().equals(playerId)) {
+            String gossipMessage = WHITE + "[" + RESET + MAGENTA + this.player.getPlayerName() +  WHITE + "] " + RESET + CYAN + msg + RESET;
+            playerManager.getAllPlayersMap().forEach((s, destinationPlayer) -> {
+                if (destinationPlayer.getPlayerId().equals(playerId)) {
                     write(gossipMessage);
                 } else {
-                    channelUtils.write(next.getPlayerId(), gossipMessage + "\r\n", true);
+                    channelUtils.write(destinationPlayer.getPlayerId(), gossipMessage + "\r\n", true);
                 }
-            }
+            });
             gameManager.getGossipCache().addGossipLine(gossipMessage);
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 
     private String getBotCommandOutput(String cmd) {
diff --git a/src/main/java/com/comandante/creeper/command/HelpCommand.java b/src/main/java/com/comandante/creeper/command/HelpCommand.java
index 72057fc51d33945f2d8bb9b0a721f3326de2d55e..57c162ff19fcc4da635d4b159b920054888b5066 100644
--- a/src/main/java/com/comandante/creeper/command/HelpCommand.java
+++ b/src/main/java/com/comandante/creeper/command/HelpCommand.java
@@ -27,8 +27,7 @@ public class HelpCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             StringBuilder sb = new StringBuilder();
             Table t = new Table(2, BorderStyle.CLASSIC_COMPATIBLE,
                     ShownBorders.HEADER_FIRST_AND_LAST_COLLUMN);
@@ -52,8 +51,6 @@ public class HelpCommand extends Command {
             sb.append(t.render());
             sb.append("\r\n");
             write(sb.toString());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/InventoryCommand.java b/src/main/java/com/comandante/creeper/command/InventoryCommand.java
index 5944e0cf35d43e6e7f72647742a367d41d1d6cd7..118faaddae4c84bc5c7e6be775e3a500df186f64 100644
--- a/src/main/java/com/comandante/creeper/command/InventoryCommand.java
+++ b/src/main/java/com/comandante/creeper/command/InventoryCommand.java
@@ -24,8 +24,7 @@ public class InventoryCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        this.execCommand(ctx, e, () -> {
             List<Item> inventory = player.getInventory();
             if (inventory == null) {
                 write("You aren't carrying anything.");
@@ -37,8 +36,6 @@ public class InventoryCommand extends Command {
             String join = StringUtils.join(player.getRolledUpIntentory().toArray(), "\r\n");
             inventoryString.append(join);
             write(inventoryString.toString());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/KillTallyCommand.java b/src/main/java/com/comandante/creeper/command/KillTallyCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e8aa8836ff46fd2a16c228e7497011108bda1fb
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/KillTallyCommand.java
@@ -0,0 +1,40 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.managers.GameManager;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.nocrala.tools.texttablefmt.BorderStyle;
+import org.nocrala.tools.texttablefmt.ShownBorders;
+import org.nocrala.tools.texttablefmt.Table;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class KillTallyCommand extends Command {
+
+    final static List<String> validTriggers = Arrays.asList("killtally", "kt", "tally");
+    final static String description = "View your kill tally.";
+    final static String correctUsage = "tally";
+
+    public KillTallyCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        this.execCommand(ctx, e, () -> {
+            Table table = new Table(2, BorderStyle.CLASSIC_COMPATIBLE, ShownBorders.HEADER_ONLY);
+            table.setColumnWidth(0, 22, 30);
+            table.setColumnWidth(1, 10, 20);
+            table.addCell("Npc");
+            table.addCell("# Killed");
+            Map<String, Long> npcKillLog = player.getNpcKillLog();
+            npcKillLog.forEach((s, aLong) -> {
+                table.addCell(s);
+                table.addCell(String.valueOf(aLong));
+            });
+            write(table.render());
+        });
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/LeaveCommand.java b/src/main/java/com/comandante/creeper/command/LeaveCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..e76ca5c88ee1ffdd0feada926ac07d86e8846e23
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/LeaveCommand.java
@@ -0,0 +1,38 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.player.PlayerMovement;
+import com.comandante.creeper.world.RemoteExit;
+import com.comandante.creeper.world.Room;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+public class LeaveCommand extends Command {
+    final static List<String> validTriggers = Arrays.asList("leave");
+    final static String description = "Enters a Leave exit";
+    final static String correctUsage = "leave";
+
+    public LeaveCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+            PlayerMovement playerMovement;
+            List<RemoteExit> leave = currentRoom.getEnterExits().stream().filter(remoteExit -> remoteExit.getExitDetail().equalsIgnoreCase("leave")).collect(Collectors.toList());
+            if (leave.size() > 0) {
+                Room destinationRoom = roomManager.getRoom(leave.get(0).getRoomId());
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "entered " + leave.get(0).getExitDetail() + ".", "N/A");
+                player.movePlayer(playerMovement);
+                return;
+            }
+            write("There is no Leave exit." + "\r\n");
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/LookCommand.java b/src/main/java/com/comandante/creeper/command/LookCommand.java
index 1a0062af9db8813e0b547cb4cce9b6b0448e7177..8c3709804659a90d10dba2e218d5a887230cd091 100644
--- a/src/main/java/com/comandante/creeper/command/LookCommand.java
+++ b/src/main/java/com/comandante/creeper/command/LookCommand.java
@@ -3,6 +3,7 @@ package com.comandante.creeper.command;
 
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.npc.Npc;
+import com.comandante.creeper.player.Levels;
 import com.comandante.creeper.player.Player;
 import com.google.common.base.Joiner;
 import org.jboss.netty.channel.ChannelHandlerContext;
@@ -22,10 +23,9 @@ public class LookCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
-                currentRoomLogic();
+                printCurrentRoomInformation();
                 return;
             }
             originalMessageParts.remove(0);
@@ -53,11 +53,9 @@ public class LookCommand extends Command {
             for (String npcId : npcIds) {
                 Npc currentNpc = gameManager.getEntityManager().getNpcEntity(npcId);
                 if (currentNpc.getValidTriggers().contains(target)) {
-                    write(gameManager.getLookString(currentNpc) + "\r\n");
+                    write(gameManager.getLookString(currentNpc, Levels.getLevel(gameManager.getStatsModifierFactory().getStatsModifier(player).getExperience())) + "\r\n");
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/LootCommand.java b/src/main/java/com/comandante/creeper/command/LootCommand.java
index 0099f075a48c25dd38534ccca885d9c437da1319..f7d1e606e1f42c897135aff0f1a489d87577e569 100644
--- a/src/main/java/com/comandante/creeper/command/LootCommand.java
+++ b/src/main/java/com/comandante/creeper/command/LootCommand.java
@@ -25,8 +25,7 @@ public class LootCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() > 1) {
                 for (Item item : player.getInventory()) {
                     if (item.getItemTypeId() == Item.CORPSE_ID_RESERVED) {
@@ -39,9 +38,9 @@ public class LootCommand extends Command {
                             }
                             Set<Item> items = lootManager.lootItemsReturn(loot);
                             for (Item i: items) {
-                                    gameManager.acquireItem(player, i.getItemId());
-                                    write("You looted " + i.getItemName() +  " from a " + item.getItemName() + ".\r\n");
-                                }
+                                gameManager.acquireItem(player, i.getItemId(), true);
+                                write("You looted " + i.getItemName() +  " from a " + item.getItemName() + ".\r\n");
+                            }
                             if (gold < 0 && items.size() == 0) {
                                 write("You looted nothing from " + item.getItemName() + "\r\n");
                             }
@@ -52,8 +51,6 @@ public class LootCommand extends Command {
                     }
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/comandante/creeper/command/MapCommand.java b/src/main/java/com/comandante/creeper/command/MapCommand.java
index 6ded954f8bf41ae2db5ea6717e359e9a3bbbbdc3..769779c8b27b8c6cecb15b584ed93963655c9af6 100644
--- a/src/main/java/com/comandante/creeper/command/MapCommand.java
+++ b/src/main/java/com/comandante/creeper/command/MapCommand.java
@@ -5,6 +5,7 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.world.Coords;
 import com.comandante.creeper.world.Room;
+import org.apache.commons.lang.math.NumberUtils;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -24,26 +25,23 @@ public class MapCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            if (originalMessageParts.size() > 1 && isInteger(originalMessageParts.get(1))) {
+        execCommand(ctx, e, () -> {
+            if (originalMessageParts.size() > 1 && NumberUtils.isNumber(originalMessageParts.get(1))) {
                 int max = Integer.parseInt(originalMessageParts.get(1));
                 write(mapsManager.drawMap(currentRoom.getRoomId(), new Coords(max, max)));
             } else {
-                Player player = playerManager.getPlayer(playerId);
-                final Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(player).get();
+                Player player1 = playerManager.getPlayer(playerId);
+                final Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(player1).get();
                 StringBuilder sb = new StringBuilder();
 
                 if (playerCurrentRoom.getMapData().isPresent()) {
                     sb.append(playerCurrentRoom.getMapData().get()).append("\r\n");
-                    channelUtils.write(player.getPlayerId(), sb.toString());
+                    channelUtils.write(player1.getPlayerId(), sb.toString());
                 } else {
-                    channelUtils.write(player.getPlayerId(), "No map data.");
+                    channelUtils.write(player1.getPlayerId(), "No map data.");
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
 
diff --git a/src/main/java/com/comandante/creeper/command/MovementCommand.java b/src/main/java/com/comandante/creeper/command/MovementCommand.java
index b05384736f87a97c3918d610a8e1fc74e8c06012..ff8a125ebd21a03f89cd65dc8eb5160d0f5a7e22 100644
--- a/src/main/java/com/comandante/creeper/command/MovementCommand.java
+++ b/src/main/java/com/comandante/creeper/command/MovementCommand.java
@@ -12,7 +12,6 @@ import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
 import java.util.Arrays;
-import java.util.Iterator;
 import java.util.List;
 
 public class MovementCommand extends Command {
@@ -36,73 +35,70 @@ public class MovementCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        try {
-            configure(e);
+        this.execCommand(ctx, e, () -> {
             if (player.isActiveFights()) {
-                write("You can't move while in a fight!");
+                MovementCommand.this.write("You can't move while in a fight!");
                 return;
             }
             if (player.isActive(CoolDownType.DEATH)) {
-                write("You are dead and can not move.");
+                MovementCommand.this.write("You are dead and can not move.");
+                return;
+            }
+            if (player.isActiveAlertNpcStatus()) {
+                MovementCommand.this.write("You are unable to progress, but can return to where you came from by typing \"back\".");
                 return;
             }
             for (String effectId : playerManager.getPlayerMetadata(playerId).getEffects()) {
                 Effect effect = gameManager.getEntityManager().getEffectEntity(effectId);
                 if (effect.isFrozenMovement()) {
-                    write("You are frozen and can not move.");
+                    MovementCommand.this.write("You are frozen and can not move.");
                     return;
                 }
             }
-            final String command = getRootCommand(e);
+            final String command = rootCommand;
             PlayerMovement playerMovement = null;
             if (!validTriggers.contains(command.toLowerCase())) {
                 throw new RuntimeException("Malformed movement command.");
             } else if (northTriggers.contains(command.toLowerCase()) && currentRoom.getNorthId().isPresent()) {
                 Room destinationRoom = roomManager.getRoom(currentRoom.getNorthId().get());
-                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the north.", "south");
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "exited to the north.", "south");
             } else if (southTriggers.contains(command.toLowerCase()) && currentRoom.getSouthId().isPresent()) {
                 Room destinationRoom = roomManager.getRoom(currentRoom.getSouthId().get());
-                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the south.", "north");
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "exited to the south.", "north");
             } else if (eastTriggers.contains(command.toLowerCase()) && currentRoom.getEastId().isPresent()) {
                 Room destinationRoom = roomManager.getRoom(currentRoom.getEastId().get());
-                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the east.", "west");
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "exited to the east.", "west");
             } else if (westTriggers.contains(command.toLowerCase()) && currentRoom.getWestId().isPresent()) {
                 Room destinationRoom = roomManager.getRoom(currentRoom.getWestId().get());
-                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited to the west.", "east");
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "exited to the west.", "east");
             } else if (upTriggers.contains(command.toLowerCase()) && currentRoom.getUpId().isPresent()) {
                 Room destinationRoom = roomManager.getRoom(currentRoom.getUpId().get());
-                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited up.", "down");
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "exited up.", "down");
             } else if (downTriggers.contains(command.toLowerCase()) && currentRoom.getDownId().isPresent()) {
                 Room destinationRoom = roomManager.getRoom(currentRoom.getDownId().get());
-                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "exited down.", "up");
+                playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "exited down.", "up");
             } else if (enterTriggers.contains(command.toLowerCase())) {
-                Optional<RemoteExit> remoteExitOptional = doesEnterExitExist();
+                Optional<RemoteExit> remoteExitOptional = MovementCommand.this.doesEnterExitExist();
                 if (remoteExitOptional.isPresent()) {
                     Room destinationRoom = roomManager.getRoom(remoteExitOptional.get().getRoomId());
-                    playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), this, "entered " + remoteExitOptional.get().getExitDetail() + ".", "N/A");
+                    playerMovement = new PlayerMovement(player, currentRoom.getRoomId(), destinationRoom.getRoomId(), "entered " + remoteExitOptional.get().getExitDetail() + ".", "N/A");
                 } else {
-                    write("There's no where to go with that name. (" + command + ")");
+                    MovementCommand.this.write("There's no where to go with that name. (" + command + ")");
                     return;
                 }
             } else {
-                write("There's no exit in that direction. (" + command + ")");
+                MovementCommand.this.write("There's no exit in that direction. (" + command + ")");
                 return;
             }
             player.movePlayer(playerMovement);
-            if (playerMovement != null) {
-                player.setReturnDirection(Optional.of(playerMovement.getReturnDirection()));
-                currentRoomLogic(roomManager.getRoom(playerMovement.getDestinationRoomId()));
-            }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 
     private Optional<RemoteExit> doesEnterExitExist() {
         if (originalMessageParts.size() > 1) {
             String enterExitName = originalMessageParts.get(1);
             for (RemoteExit remoteExit : currentRoom.getEnterExits()) {
-                if (remoteExit.getExitDetail().equals(enterExitName)) {
+                if (remoteExit.getExitDetail().equalsIgnoreCase(enterExitName)) {
                     return Optional.of(remoteExit);
                 }
             }
diff --git a/src/main/java/com/comandante/creeper/command/NexusCommand.java b/src/main/java/com/comandante/creeper/command/NexusCommand.java
index 56e01364a2938537e9d3242c002ff6141af6c7c7..be8c757e23542ac2efcb2afd999d9a4a50a43bb3 100644
--- a/src/main/java/com/comandante/creeper/command/NexusCommand.java
+++ b/src/main/java/com/comandante/creeper/command/NexusCommand.java
@@ -20,8 +20,7 @@ public class NexusCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (gameManager.getCreeperConfiguration().isIrcEnabled) {
                 originalMessageParts.remove(0);
                 String transferPhrase = Joiner.on(" ").join(originalMessageParts);
@@ -29,8 +28,6 @@ public class NexusCommand extends Command {
                     gameManager.getIrcBotService().getBot().getUserChannelDao().getChannel(gameManager.getCreeperConfiguration().ircChannel).send().message(player.getPlayerName() + ": " + transferPhrase);
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/OpCommand.java b/src/main/java/com/comandante/creeper/command/OpCommand.java
index 7e294b30a48e19d3d9176a9b65f4cacd811033d0..4088c41b7a89f902e0a72ec91870d824c5ca9b61 100644
--- a/src/main/java/com/comandante/creeper/command/OpCommand.java
+++ b/src/main/java/com/comandante/creeper/command/OpCommand.java
@@ -1,19 +1,13 @@
 package com.comandante.creeper.command;
 
-import com.comandante.creeper.CreeperEntry;
 import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.merchant.Merchant;
-import com.comandante.creeper.merchant.lockers.LockerCommand;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 import org.pircbotx.Channel;
-import org.pircbotx.PircBotX;
 import org.pircbotx.User;
 import org.pircbotx.UserChannelDao;
 
@@ -38,8 +32,7 @@ public class OpCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             //ghetto and will only work for one channel bots.
             if (originalMessageParts.size() <= 1) {
                 return;
@@ -54,11 +47,9 @@ public class OpCommand extends Command {
             }
             ImmutableSortedSet<Channel> channels = user.getChannels();
             for (Channel channel : channels) {
-                    channel.send().op(user);
-                    write("Ops given in channel " + channel.getName());
-                }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+                channel.send().op(user);
+                write("Ops given in channel " + channel.getName());
+            }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/OpenCommand.java b/src/main/java/com/comandante/creeper/command/OpenCommand.java
index 1caae810735649f1c4ad090dc4923c805324a6bd..6c2a1ac21f9e50f0a0b098f6936b18b88424b8ee 100644
--- a/src/main/java/com/comandante/creeper/command/OpenCommand.java
+++ b/src/main/java/com/comandante/creeper/command/OpenCommand.java
@@ -5,18 +5,14 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.merchant.Merchant;
 import com.comandante.creeper.merchant.lockers.LockerCommand;
 import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
-/**
- * Created by kearney on 6/12/15.
- */
 public class OpenCommand extends Command {
 
     final static List<String> validTriggers = Arrays.asList("open", "o");
@@ -29,10 +25,10 @@ public class OpenCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        OpenCommand openCommand = this;
+        execCommand(ctx, e, () -> {
             if (creeperSession.getGrabMerchant().isPresent()) {
-                creeperSession.setGrabMerchant(Optional.<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>>absent());
+                creeperSession.setGrabMerchant(Optional.empty());
                 return;
             }
             originalMessageParts.remove(0);
@@ -45,12 +41,9 @@ public class OpenCommand extends Command {
                 if (merchant.getValidTriggers().contains(desiredMerchantTalk)) {
                     write(merchant.getWelcomeMessage() + "\r\n");
                     write(LockerCommand.getPrompt());
-                    creeperSession.setGrabMerchant(Optional.of(
-                            new CreeperEntry<Merchant, SimpleChannelUpstreamHandler>(merchant, this)));
+                    creeperSession.setGrabMerchant(Optional.of(new CreeperEntry<>(merchant, openCommand)));
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/PickUpCommand.java b/src/main/java/com/comandante/creeper/command/PickUpCommand.java
index a60b8bea0441447a1297603727583962d673dace..6a8614dbc4aa1f8a19aff2431008c2dd33d23324 100644
--- a/src/main/java/com/comandante/creeper/command/PickUpCommand.java
+++ b/src/main/java/com/comandante/creeper/command/PickUpCommand.java
@@ -22,8 +22,7 @@ public class PickUpCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             Set<String> itemIds = currentRoom.getItemIds();
             originalMessageParts.remove(0);
             String desiredPickUpItem = Joiner.on(" ").join(originalMessageParts);
@@ -39,8 +38,6 @@ public class PickUpCommand extends Command {
                     }
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/QuitCommand.java b/src/main/java/com/comandante/creeper/command/QuitCommand.java
index 143fe5e3053326f3b2df3e40191e40f6615cddb7..f21ee77d6055b839e2d0cd75c617465a61fce33d 100644
--- a/src/main/java/com/comandante/creeper/command/QuitCommand.java
+++ b/src/main/java/com/comandante/creeper/command/QuitCommand.java
@@ -19,11 +19,12 @@ public class QuitCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        if (player.getActiveFights().size() > 0) {
-            write("You can't quit in the middle of a fight!");
-        } else {
-            gameManager.getPlayerManager().removePlayer(creeperSession.getUsername().get());
-        }
+        execCommand(ctx, e, () -> {
+            if (player.getActiveFights().size() > 0) {
+                write("You can't quit in the middle of a fight!");
+            } else {
+                gameManager.getPlayerManager().removePlayer(creeperSession.getUsername().get());
+            }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/RecentChangesCommand.java b/src/main/java/com/comandante/creeper/command/RecentChangesCommand.java
index de3a324485b29b90610188efd7a21b36e56ba660..997b96600784e9ff88d70823ce74fcc459a7f12c 100644
--- a/src/main/java/com/comandante/creeper/command/RecentChangesCommand.java
+++ b/src/main/java/com/comandante/creeper/command/RecentChangesCommand.java
@@ -7,6 +7,7 @@ import org.jboss.netty.channel.MessageEvent;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
 
 public class RecentChangesCommand extends Command {
 
@@ -20,11 +21,12 @@ public class RecentChangesCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            write(RecentChangesManager.getRecentChanges());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        execCommandBackgroundThread(ctx, e, () -> {
+            try {
+                write(RecentChangesManager.getRecentChanges());
+            } catch (ExecutionException ex) {
+                log.error("Unable to retrieve recent changes.", ex);
+            }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/RecentGossipCommand.java b/src/main/java/com/comandante/creeper/command/RecentGossipCommand.java
index a7e5677c25a0499a381c2c36af2efd180dcf6689..ea11c2fd0fa603f6a296a4c5032aabf5563e5bae 100644
--- a/src/main/java/com/comandante/creeper/command/RecentGossipCommand.java
+++ b/src/main/java/com/comandante/creeper/command/RecentGossipCommand.java
@@ -20,8 +20,7 @@ public class RecentGossipCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             List<String> recent = null;
             if (originalMessageParts.size() > 1) {
                 String size = originalMessageParts.get(1);
@@ -38,8 +37,6 @@ public class RecentGossipCommand extends Command {
             for (String line : recent) {
                 write(line + "\r\n");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/SayCommand.java b/src/main/java/com/comandante/creeper/command/SayCommand.java
index e196503c97c5f36742441bed7d3d6e5abcbc4c01..11715d00ade27391699e91415833ad14a9ea6c5b 100644
--- a/src/main/java/com/comandante/creeper/command/SayCommand.java
+++ b/src/main/java/com/comandante/creeper/command/SayCommand.java
@@ -26,20 +26,19 @@ public class SayCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             originalMessageParts.remove(0);
             String message = Joiner.on(" ").join(originalMessageParts);
             Set<Player> presentPlayers = roomManager.getPresentPlayers(currentRoom);
             for (Player presentPlayer : presentPlayers) {
-                StringBuilder stringBuilder = new StringBuilder();
-                stringBuilder.append(RED);
-                stringBuilder.append("<").append(player.getPlayerName()).append("> ").append(message);
-                stringBuilder.append(RESET);
+                StringBuilder sb = new StringBuilder();
+                sb.append(RED);
+                sb.append("<").append(player.getPlayerName()).append("> ").append(message);
+                sb.append(RESET);
                 if (presentPlayer.getPlayerId().equals(playerId)) {
-                    write(stringBuilder.toString());
+                    write(sb.toString());
                 } else {
-                    channelUtils.write(presentPlayer.getPlayerId(), stringBuilder.append("\r\n").toString(), true);
+                    channelUtils.write(presentPlayer.getPlayerId(), sb.append("\r\n").toString(), true);
                 }
             }
             if (gameManager.getCreeperConfiguration().isIrcEnabled && (Objects.equals(gameManager.getCreeperConfiguration().ircBridgeRoomId, currentRoom.getRoomId()))) {
@@ -47,8 +46,6 @@ public class SayCommand extends Command {
                     gameManager.getIrcBotService().getBot().getUserChannelDao().getChannel(gameManager.getCreeperConfiguration().ircChannel).send().message(player.getPlayerName() + ": " + message);
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/SetCommand.java b/src/main/java/com/comandante/creeper/command/SetCommand.java
index 21a3ef52089f02863f8f25b08b7de499337627fe..e675700837ee38dd5c628d676b33d52bfcb181d7 100644
--- a/src/main/java/com/comandante/creeper/command/SetCommand.java
+++ b/src/main/java/com/comandante/creeper/command/SetCommand.java
@@ -1,6 +1,5 @@
 package com.comandante.creeper.command;
 
-import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerSettings;
 import com.google.api.client.util.Lists;
@@ -22,8 +21,7 @@ public class SetCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             write("'set help' for full settings help.\r\n");
             if (originalMessageParts.size() <= 1) {
                 write(returnAllSettings());
@@ -43,9 +41,7 @@ public class SetCommand extends Command {
             } else {
                 write ("Unknown Setting.\r\n");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 
     private String returnAllSettings() {
diff --git a/src/main/java/com/comandante/creeper/command/ShowCommand.java b/src/main/java/com/comandante/creeper/command/ShowCommand.java
index 30a56c484998305c25c87e6e80545d60e832caad..d60622c0edb7605022d7780758229c9d0df5e05e 100644
--- a/src/main/java/com/comandante/creeper/command/ShowCommand.java
+++ b/src/main/java/com/comandante/creeper/command/ShowCommand.java
@@ -2,14 +2,7 @@ package com.comandante.creeper.command;
 
 import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.player.CoolDownType;
-import com.comandante.creeper.player.Player;
-import com.comandante.creeper.player.PlayerMovement;
-import com.comandante.creeper.player.PlayerRole;
-import com.comandante.creeper.server.Color;
-import com.comandante.creeper.world.Room;
 import com.google.common.base.Joiner;
-import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -26,8 +19,7 @@ public class ShowCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() <= 1) {
                 return;
             }
@@ -41,8 +33,6 @@ public class ShowCommand extends Command {
                     }
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/SpellsCommand.java b/src/main/java/com/comandante/creeper/command/SpellsCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..abd871498ff5659fe35230d017f003452526658c
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/SpellsCommand.java
@@ -0,0 +1,33 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.managers.GameManager;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+
+import java.util.Arrays;
+import java.util.List;
+
+
+public class SpellsCommand extends Command {
+    final static List<String> validTriggers = Arrays.asList("spells");
+    final static String description = "Lists the spells that a player has learned.";
+    final static String correctUsage = "show <item_name>";
+
+    public SpellsCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+            StringBuilder sb = new StringBuilder();
+            List<String> learnedSpells = player.getLearnedSpells();
+            if (learnedSpells.size() == 0) {
+                write("You haven't learned any spells." + "\r\n");
+                return;
+            }
+            learnedSpells.forEach(s -> sb.append(s).append("\r\n"));
+            write(sb.append("\r\n").toString());
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/TalkCommand.java b/src/main/java/com/comandante/creeper/command/TalkCommand.java
index b8795638a8c88cf11db4e64dafee1e8b9e7b2692..6abae37484b01e6f878277ec5979744ad4d31ed4 100644
--- a/src/main/java/com/comandante/creeper/command/TalkCommand.java
+++ b/src/main/java/com/comandante/creeper/command/TalkCommand.java
@@ -8,13 +8,13 @@ import com.comandante.creeper.merchant.MerchantCommandHandler;
 import com.comandante.creeper.merchant.bank.commands.BankCommand;
 import com.comandante.creeper.merchant.lockers.LockerCommand;
 import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 public class TalkCommand extends Command {
@@ -29,10 +29,10 @@ public class TalkCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        TalkCommand talkCommand = this;
+        execCommand(ctx, e, () -> {
             if (creeperSession.getGrabMerchant().isPresent()) {
-                creeperSession.setGrabMerchant(Optional.<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>>absent());
+                creeperSession.setGrabMerchant(Optional.empty());
                 return;
             }
             originalMessageParts.remove(0);
@@ -50,11 +50,9 @@ public class TalkCommand extends Command {
                         write(LockerCommand.getPrompt());
                     }
                     creeperSession.setGrabMerchant(Optional.of(
-                            new CreeperEntry<Merchant, SimpleChannelUpstreamHandler>(merchant, this)));
+                            new CreeperEntry<>(merchant, talkCommand)));
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/TellCommand.java b/src/main/java/com/comandante/creeper/command/TellCommand.java
index 66f8d34619c0cf02e464eca212a982cc61889217..3a95fa8b2cda856f28d175d09681bf76fab63e14 100644
--- a/src/main/java/com/comandante/creeper/command/TellCommand.java
+++ b/src/main/java/com/comandante/creeper/command/TellCommand.java
@@ -24,8 +24,7 @@ public class TellCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() < 3) {
                 write("tell failed, no message to send.");
                 return;
@@ -51,8 +50,6 @@ public class TellCommand extends Command {
             stringBuilder.append(RESET);
             channelUtils.write(desintationPlayer.getPlayerId(), destinationPlayercolor + stringBuilder.append("\r\n").toString(), true);
             write(stringBuilder.toString());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/TimeCommand.java b/src/main/java/com/comandante/creeper/command/TimeCommand.java
index 0ac03d426a6d00c4f6968af12146100516a43dc8..f714398cfacee1cc4ea259e80cc4f4aaf49ca0bb 100644
--- a/src/main/java/com/comandante/creeper/command/TimeCommand.java
+++ b/src/main/java/com/comandante/creeper/command/TimeCommand.java
@@ -1,16 +1,13 @@
 package com.comandante.creeper.command;
 
-import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.world.TimeTracker;
-import com.google.common.base.Joiner;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.Set;
 
 public class TimeCommand extends Command {
     final static List<String> validTriggers = Arrays.asList("time");
@@ -23,12 +20,9 @@ public class TimeCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             TimeTracker.TimeOfDay timeOfDay = gameManager.getTimeTracker().getTimeOfDay();
             write(timeOfDay.color + timeOfDay + Color.RESET);
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/UnequipCommand.java b/src/main/java/com/comandante/creeper/command/UnequipCommand.java
index c337b900b07a375b8423b4d6eaa9e8e412fe81df..ac4e54feb1d2743caf4da7461f6e863cc6fee246 100644
--- a/src/main/java/com/comandante/creeper/command/UnequipCommand.java
+++ b/src/main/java/com/comandante/creeper/command/UnequipCommand.java
@@ -22,8 +22,7 @@ public class UnequipCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
                 write("No equipment item specified.");
                 return;
@@ -38,8 +37,6 @@ public class UnequipCommand extends Command {
                 }
             }
             write("Item is not currently equipped.");
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/UnknownCommand.java b/src/main/java/com/comandante/creeper/command/UnknownCommand.java
index 068c9b29eb5ee3236ac8d5a116871ea5116e1ae5..9a76b0792efc1105b11e2bd4d5120200df2c6393 100644
--- a/src/main/java/com/comandante/creeper/command/UnknownCommand.java
+++ b/src/main/java/com/comandante/creeper/command/UnknownCommand.java
@@ -12,11 +12,6 @@ public class UnknownCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            write(getPrompt(), false);
-            e.getChannel().getPipeline().remove(ctx.getHandler());
-        } finally {
-        }
+        removeCurrentHandlerAndWritePrompt(ctx, e, false);
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/UseCommand.java b/src/main/java/com/comandante/creeper/command/UseCommand.java
index 0812762ed1012676cc17f2adaa71d33dd75c95c5..e04458b63c66366b8bf381a55e8e3b5b7384c0b2 100644
--- a/src/main/java/com/comandante/creeper/command/UseCommand.java
+++ b/src/main/java/com/comandante/creeper/command/UseCommand.java
@@ -2,7 +2,6 @@ package com.comandante.creeper.command;
 
 
 import com.comandante.creeper.Items.Item;
-import com.comandante.creeper.Items.ItemUseHandler;
 import com.comandante.creeper.managers.GameManager;
 import com.google.common.base.Joiner;
 import org.jboss.netty.channel.ChannelHandlerContext;
@@ -23,8 +22,7 @@ public class UseCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
                 write("No item specified.");
                 return;
@@ -37,8 +35,6 @@ public class UseCommand extends Command {
                 return;
             }
             gameManager.getItemUseHandler().handle(player, inventoryItem);
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/UsersCommand.java b/src/main/java/com/comandante/creeper/command/UsersCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..77c1e1e31edb5c0f76d1cc6ecd643554b594397e
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/command/UsersCommand.java
@@ -0,0 +1,141 @@
+package com.comandante.creeper.command;
+
+import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.player.Player;
+import com.comandante.creeper.player.PlayerRole;
+import com.google.common.collect.Sets;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.nocrala.tools.texttablefmt.BorderStyle;
+import org.nocrala.tools.texttablefmt.ShownBorders;
+import org.nocrala.tools.texttablefmt.Table;
+
+import java.net.InetSocketAddress;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+public class UsersCommand extends Command {
+
+    final static List<String> validTriggers = Arrays.asList("users");
+    final static String description = "Display extended inforation about who is logged in.";
+    final static String correctUsage = "users";
+
+    public UsersCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage, null);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+            Table t = new Table(4, BorderStyle.BLANKS,
+                    ShownBorders.NONE);
+            t.setColumnWidth(0, 14, 24);
+            t.setColumnWidth(1, 18, 18);
+            t.setColumnWidth(2, 21, 21);
+            t.addCell("Player");
+            t.addCell("IP");
+            t.addCell("Logged in since");
+            t.addCell("Idle");
+            Set<Player> allPlayers = gameManager.getAllPlayers();
+            for (Player allPlayer : allPlayers) {
+                t.addCell(allPlayer.getPlayerName());
+
+                InetSocketAddress remoteAddress = (InetSocketAddress) allPlayer.getChannel().getRemoteAddress();
+                String remoteUsersHost = remoteAddress.getHostString();
+                t.addCell(remoteUsersHost);
+
+                SimpleDateFormat loggedInFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
+                String loginTime = loggedInFormat.format(new Date(playerManager.getSessionManager().getSession(allPlayer.getPlayerId()).getInitialLoginTime()));
+                t.addCell(loginTime);
+
+                long lastActivity = playerManager.getSessionManager().getSession(allPlayer.getPlayerId()).getLastActivity();
+                String idleTime = getFriendlyTime(new Date(lastActivity));
+                t.addCell(idleTime);
+            }
+            write(t.render());
+        });
+    }
+
+    public static String getFriendlyTime(Date dateTime) {
+        StringBuffer sb = new StringBuffer();
+        Date current = Calendar.getInstance().getTime();
+        long diffInSeconds = (current.getTime() - dateTime.getTime()) / 1000;
+
+        long sec = (diffInSeconds >= 60 ? diffInSeconds % 60 : diffInSeconds);
+        long min = (diffInSeconds = (diffInSeconds / 60)) >= 60 ? diffInSeconds % 60 : diffInSeconds;
+        long hrs = (diffInSeconds = (diffInSeconds / 60)) >= 24 ? diffInSeconds % 24 : diffInSeconds;
+        long days = (diffInSeconds = (diffInSeconds / 24)) >= 30 ? diffInSeconds % 30 : diffInSeconds;
+        long months = (diffInSeconds = (diffInSeconds / 30)) >= 12 ? diffInSeconds % 12 : diffInSeconds;
+        long years = (diffInSeconds = (diffInSeconds / 12));
+
+        if (years > 0) {
+            if (years == 1) {
+                sb.append("a year");
+            } else {
+                sb.append(years + " years");
+            }
+            if (years <= 6 && months > 0) {
+                if (months == 1) {
+                    sb.append(" and a month");
+                } else {
+                    sb.append(" and " + months + " months");
+                }
+            }
+        } else if (months > 0) {
+            if (months == 1) {
+                sb.append("a month");
+            } else {
+                sb.append(months + " months");
+            }
+            if (months <= 6 && days > 0) {
+                if (days == 1) {
+                    sb.append(" and a day");
+                } else {
+                    sb.append(" and " + days + " days");
+                }
+            }
+        } else if (days > 0) {
+            if (days == 1) {
+                sb.append("a day");
+            } else {
+                sb.append(days + " days");
+            }
+            if (days <= 3 && hrs > 0) {
+                if (hrs == 1) {
+                    sb.append(" and an hour");
+                } else {
+                    sb.append(" and " + hrs + " hours");
+                }
+            }
+        } else if (hrs > 0) {
+            if (hrs == 1) {
+                sb.append("an hour");
+            } else {
+                sb.append(hrs + " hours");
+            }
+            if (min > 1) {
+                sb.append(" and " + min + " minutes");
+            }
+        } else if (min > 0) {
+            if (min == 1) {
+                sb.append("a minute");
+            } else {
+                sb.append(min + " minutes");
+            }
+            if (sec > 1) {
+                sb.append(" and " + sec + " seconds");
+            }
+        } else {
+            if (sec <= 1) {
+                sb.append("about a second");
+            } else {
+                sb.append("about " + sec + " seconds");
+            }
+        }
+        return sb.toString();
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/WhoCommand.java b/src/main/java/com/comandante/creeper/command/WhoCommand.java
old mode 100755
new mode 100644
index abce565448dd85acc16f55eea84938553d411e54..c89def626da24270bb51bb5f7ddb9f66214dfd11
--- a/src/main/java/com/comandante/creeper/command/WhoCommand.java
+++ b/src/main/java/com/comandante/creeper/command/WhoCommand.java
@@ -27,10 +27,9 @@ public class WhoCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             StringBuilder output = new StringBuilder();
-           // output.append(Color.MAGENTA + "Who--------------------------------" + Color.RESET).append("\r\n");
+            // output.append(Color.MAGENTA + "Who--------------------------------" + Color.RESET).append("\r\n");
             Table t = new Table(4, BorderStyle.BLANKS,
                     ShownBorders.NONE);
             t.setColumnWidth(0, 14, 24);
@@ -49,8 +48,6 @@ public class WhoCommand extends Command {
             }
             output.append(t.render());
             write(output.toString());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/WhoamiCommand.java b/src/main/java/com/comandante/creeper/command/WhoamiCommand.java
index 7a526fce3aa829b578ad3b5b022f47e93a446efd..6c73a13d8cc0dcfc61794a0dc9f1327a6493319c 100644
--- a/src/main/java/com/comandante/creeper/command/WhoamiCommand.java
+++ b/src/main/java/com/comandante/creeper/command/WhoamiCommand.java
@@ -18,11 +18,6 @@ public class WhoamiCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            write(player.getPlayerName());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        execCommand(ctx, e, () -> write(player.getPlayerName()));
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/XpCommand.java b/src/main/java/com/comandante/creeper/command/XpCommand.java
index 869b816bbed6fae8efbe1f02e0f1086be4538284..85dc03f457a0724d0a55c0d0acfe819e7e36e678 100644
--- a/src/main/java/com/comandante/creeper/command/XpCommand.java
+++ b/src/main/java/com/comandante/creeper/command/XpCommand.java
@@ -31,34 +31,27 @@ public class XpCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             PlayerMetadata playerMetadata = playerManager.getPlayerMetadata(player.getPlayerId());
             long nextLevel = Levels.getLevel(playerMetadata.getStats().getExperience()) + 1;
             long expToNextLevel = Levels.getXp(nextLevel) - playerMetadata.getStats().getExperience();
             Meter meter = Main.metrics.meter("experience-" + player.getPlayerName());
-            StringBuilder sb = new StringBuilder();
-            sb.append(NumberFormat.getNumberInstance(Locale.US).format(expToNextLevel)).append(" experience to level ").append(nextLevel).append(".\r\n");
 
-            Table t = new Table(2, BorderStyle.CLASSIC_COMPATIBLE,
-                    ShownBorders.NONE);
-
-            t.setColumnWidth(0, 8, 20);
-            t.setColumnWidth(1, 10, 20);
-
-
-            t.addCell("Window");
-            t.addCell("XP/sec");
-            t.addCell(" 1 min");
-            t.addCell(String.valueOf(round(meter.getOneMinuteRate())));
-            t.addCell(" 5 min");
-            t.addCell(String.valueOf(round(meter.getFiveMinuteRate())));
-            t.addCell("15 min");
-            t.addCell(String.valueOf(round(meter.getFifteenMinuteRate())));
-            write(sb.toString() + t.render());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+            Table table = new Table(2, BorderStyle.CLASSIC_COMPATIBLE, ShownBorders.NONE);
+
+            table.setColumnWidth(0, 8, 20);
+            table.setColumnWidth(1, 10, 20);
+            table.addCell("Window");
+            table.addCell("XP/sec");
+            table.addCell(" 1 min");
+            table.addCell(String.valueOf(round(meter.getOneMinuteRate())));
+            table.addCell(" 5 min");
+            table.addCell(String.valueOf(round(meter.getFiveMinuteRate())));
+            table.addCell("15 min");
+            table.addCell(String.valueOf(round(meter.getFifteenMinuteRate())));
+
+            write(NumberFormat.getNumberInstance(Locale.US).format(expToNextLevel) + " experience to level " + nextLevel + ".\r\n" + table.render());
+        });
     }
 
     public static double round(double value) {
diff --git a/src/main/java/com/comandante/creeper/command/admin/AreaCommand.java b/src/main/java/com/comandante/creeper/command/admin/AreaCommand.java
index 3cc26a63db5d5e27265454e18ee6902790b57966..9d20b36a0fd0ea6c889707f63f2a8ca66f665717 100644
--- a/src/main/java/com/comandante/creeper/command/admin/AreaCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/AreaCommand.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.comandante.creeper.world.Area;
@@ -25,11 +26,10 @@ public class AreaCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() == 1) {
                 Set<Area> areas = currentRoom.getAreas();
-                for (Area area: areas) {
+                for (Area area : areas) {
                     write(area.getName() + "\r\n");
                 }
                 return;
@@ -37,7 +37,7 @@ public class AreaCommand extends Command {
             String s = originalMessageParts.get(1);
             List<String> strings = Arrays.asList(s.split(","));
             Set<Area> newAreas = Sets.newConcurrentHashSet();
-            for (String string: strings) {
+            for (String string : strings) {
                 String trim = string.trim();
                 Area byName = Area.getByName(trim);
                 if (byName != null) {
@@ -48,8 +48,6 @@ public class AreaCommand extends Command {
                     write(byName + " is not a known area in the code base.");
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/BounceIrcBotCommand.java b/src/main/java/com/comandante/creeper/command/admin/BounceIrcBotCommand.java
index e518ed20354e714102375ebb9e7b441c9443ab4d..30fd2fe2fbe4a97df5ff63f8f8af61f6e0db57b2 100644
--- a/src/main/java/com/comandante/creeper/command/admin/BounceIrcBotCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/BounceIrcBotCommand.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.collect.Sets;
@@ -25,9 +26,8 @@ public class BounceIrcBotCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        try {
-            synchronized (BounceIrcBotCommand.class) {
-                configure(e);
+        execCommandThreadSafe(ctx, e, BounceIrcBotCommand.class, () -> {
+            try {
                 MultiBotManager<PircBotX> manager = gameManager.getIrcBotService().getManager();
                 write("IRC Bot Service shutting down.\r\n");
                 manager.stopAndWait();
@@ -36,9 +36,9 @@ public class BounceIrcBotCommand extends Command {
                 multiBotManager.start();
                 gameManager.getIrcBotService().setManager(multiBotManager);
                 write("IRC Bot Service started.\r\n");
+            } catch (Exception ex) {
+                log.error("Unable to restart IRC service", ex);
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/admin/BuildCommand.java b/src/main/java/com/comandante/creeper/command/admin/BuildCommand.java
index ea089cfb97148b2c4f7116c7c638ed6bc055e389..e7f43e3a49d2f9f27b491938624c378a6ec1469d 100644
--- a/src/main/java/com/comandante/creeper/command/admin/BuildCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/BuildCommand.java
@@ -5,21 +5,17 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerMovement;
 import com.comandante.creeper.player.PlayerRole;
 import com.comandante.creeper.world.*;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
+import java.util.stream.Collectors;
 
 public class BuildCommand extends Command {
 
-    final static List<String> validTriggers = Arrays.asList("build", "b");
+    final static List<String> validTriggers = Arrays.asList("build");
     final static String description = "Build new rooms in the world.";
     final static String correctUsage = "build [n|s|e|w|enter <name>|notable <name>]";
     final static Set<PlayerRole> roles = Sets.newHashSet(PlayerRole.ADMIN);
@@ -30,8 +26,7 @@ public class BuildCommand extends Command {
 
     @Override
     public synchronized void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() > 1) {
                 String desiredBuildDirection = originalMessageParts.get(1);
                 if (desiredBuildDirection.equalsIgnoreCase("notable")) {
@@ -79,13 +74,7 @@ public class BuildCommand extends Command {
                                 .setDownId(Optional.of(currentRoom.getRoomId()))
                                 .createBasicRoom();
                         currentRoom.setUpId(Optional.of(newRoomId));
-                        entityManager.addEntity(basicRoom);
-                        newFloorModel.setRoomModels(Sets.newHashSet(Iterators.transform(Sets.newHashSet(basicRoom).iterator(), WorldExporter.buildRoomModelsFromRooms())));
-                        floorManager.addFloor(newFloorModel.getId(), newFloorModel.getName());
-                        mapsManager.addFloorMatrix(newFloorModel.getId(), MapMatrix.createMatrixFromCsv(newFloorModel.getRawMatrixCsv()));
-                        mapsManager.generateAllMaps();
-                        player.movePlayer(new PlayerMovement(player, currentRoom.getRoomId(), basicRoom.getRoomId(), null, "", ""));
-                        gameManager.currentRoomLogic(player.getPlayerId());
+                        addNewRoomAndFloorAndMovePlayer(basicRoom, newFloorModel, Optional.empty());
                         return;
                     }
                 } else if (desiredBuildDirection.equalsIgnoreCase("d") | desiredBuildDirection.equalsIgnoreCase("down")) {
@@ -102,16 +91,14 @@ public class BuildCommand extends Command {
                                 .setUpId(Optional.of(currentRoom.getRoomId()))
                                 .createBasicRoom();
                         currentRoom.setDownId(Optional.of(newRoomId));
-                        entityManager.addEntity(basicRoom);
-                        newFloorModel.setRoomModels(Sets.newHashSet(Iterators.transform(Sets.newHashSet(basicRoom).iterator(), WorldExporter.buildRoomModelsFromRooms())));
-                        floorManager.addFloor(newFloorModel.getId(), newFloorModel.getName());
-                        mapsManager.addFloorMatrix(newFloorModel.getId(), MapMatrix.createMatrixFromCsv(newFloorModel.getRawMatrixCsv()));
-                        mapsManager.generateAllMaps();
-                        player.movePlayer(new PlayerMovement(player, currentRoom.getRoomId(), basicRoom.getRoomId(), null, "", ""));
-                        gameManager.currentRoomLogic(player.getPlayerId());
+                        addNewRoomAndFloorAndMovePlayer(basicRoom, newFloorModel, Optional.empty());
                         return;
                     }
                 } else if (desiredBuildDirection.equalsIgnoreCase("enter")) {
+                    if (originalMessageParts.size() != 3) {
+                        channelUtils.write(playerId, "Must specify a name for new \"enter\"");
+                        return;
+                    }
                     String enterName = originalMessageParts.get(2);
                     Integer newRoomId = findUnusedRoomId();
                     Integer newFloorId = findUnusedFloorId();
@@ -125,25 +112,12 @@ public class BuildCommand extends Command {
                             .addEnterExit(returnRemoteExit)
                             .createBasicRoom();
                     currentRoom.addEnterExit(remoteExit);
-                    entityManager.addEntity(basicRoom);
-                    newFloorModel.setRoomModels(Sets.newHashSet(Iterators.transform(Sets.newHashSet(basicRoom).iterator(), WorldExporter.buildRoomModelsFromRooms())));
-                    floorManager.addFloor(newFloorModel.getId(), newFloorModel.getName());
-                    MapMatrix matrixFromCsv = MapMatrix.createMatrixFromCsv(newFloorModel.getRawMatrixCsv());
-                    matrixFromCsv.addRemote(basicRoom.getRoomId(), returnRemoteExit);
-                    mapsManager.addFloorMatrix(newFloorModel.getId(), matrixFromCsv);
-                    mapsManager.generateAllMaps();
-                    player.movePlayer(new PlayerMovement(player, currentRoom.getRoomId(), basicRoom.getRoomId(), null, "", ""));
-                    gameManager.currentRoomLogic(player.getPlayerId());
+                    addNewRoomAndFloorAndMovePlayer(basicRoom, newFloorModel, Optional.of(returnRemoteExit));
                     return;
                 }
                 channelUtils.write(playerId, "Room already exists at that location.");
             }
-        } finally
-
-        {
-            super.messageReceived(ctx, e);
-        }
-
+        });
     }
 
     private FloorModel newFloorModel(Integer floorId, Integer newRoomId, Integer currentRoomId, RemoteExit remoteExit) {
@@ -181,7 +155,7 @@ public class BuildCommand extends Command {
         rebuildExits(currentRoom, mapMatrix);
         processExits(basicRoom, mapMatrix);
         mapsManager.generateAllMaps();
-        player.movePlayer(new PlayerMovement(player, currentRoom.getRoomId(), basicRoom.getRoomId(), null, "", ""));
+        player.movePlayer(new PlayerMovement(player, currentRoom.getRoomId(), basicRoom.getRoomId(), "", ""));
         gameManager.currentRoomLogic(player.getPlayerId());
         write("Room Created.");
     }
@@ -214,7 +188,7 @@ public class BuildCommand extends Command {
         if (mapMatrix.getWesternExit(room.getRoomId()) > 0) {
             room.setWestId(Optional.of(mapMatrix.getWesternExit(room.getRoomId())));
         }
-        room.setEnterExits(Lists.<RemoteExit>newArrayList());
+        room.setEnterExits(Lists.newArrayList());
         if (mapMatrix.getRemotes().containsKey(room.getRoomId())) {
             Set<RemoteExit> remoteExits = mapMatrix.getRemotes().get(room.getRoomId());
             for (RemoteExit next : remoteExits) {
@@ -229,6 +203,21 @@ public class BuildCommand extends Command {
         }
     }
 
+    private void addNewRoomAndFloorAndMovePlayer(Room newRoom, FloorModel newFloorModel, Optional<RemoteExit> returnRemoteExit) {
+        entityManager.addEntity(newRoom);
+        Set<RoomModel> roomModels = Sets.newHashSet(newRoom).stream().map(WorldExporter.buildRoomModelsFromRooms()).collect(Collectors.toSet());
+        newFloorModel.setRoomModels(roomModels);
+        floorManager.addFloor(newFloorModel.getId(), newFloorModel.getName());
+        MapMatrix matrixFromCsv = MapMatrix.createMatrixFromCsv(newFloorModel.getRawMatrixCsv());
+        if (returnRemoteExit.isPresent()) {
+            matrixFromCsv.addRemote(newRoom.getRoomId(), returnRemoteExit.get());
+        }
+        mapsManager.addFloorMatrix(newFloorModel.getId(), matrixFromCsv);
+        mapsManager.generateAllMaps();
+        player.movePlayer(new PlayerMovement(player, currentRoom.getRoomId(), newRoom.getRoomId(), "", ""));
+        gameManager.currentRoomLogic(player.getPlayerId());
+    }
+
     private synchronized Integer findUnusedRoomId() {
         for (int i = 1; i < Integer.MAX_VALUE; i++) {
             if (!roomManager.doesRoomIdExist(i)) {
diff --git a/src/main/java/com/comandante/creeper/command/admin/DescriptionCommand.java b/src/main/java/com/comandante/creeper/command/admin/DescriptionCommand.java
index 61f8455bbb8100d1dbbdb1707d9ccb8c575d1561..34b42d7d714bca32e73d21dd8b39a275c7808d71 100644
--- a/src/main/java/com/comandante/creeper/command/admin/DescriptionCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/DescriptionCommand.java
@@ -2,11 +2,11 @@ package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.CreeperEntry;
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.comandante.creeper.server.MultiLineInputManager;
 import com.google.common.base.Joiner;
-import com.google.common.base.Optional;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
@@ -27,14 +27,14 @@ public class DescriptionCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        DescriptionCommand descriptionCommand = this;
+        execCommand(ctx, e, () -> {
             if (creeperSession.getGrabMultiLineInput().isPresent()) {
                 MultiLineInputManager multiLineInputManager = gameManager.getMultiLineInputManager();
                 UUID uuid = creeperSession.getGrabMultiLineInput().get().getKey();
                 String multiLineInput = multiLineInputManager.retrieveMultiLineInput(uuid);
                 currentRoom.setRoomDescription(multiLineInput);
-                creeperSession.setGrabMultiLineInput(Optional.<CreeperEntry<UUID, Command>>absent());
+                creeperSession.setGrabMultiLineInput(Optional.empty());
                 return;
             }
             if (originalMessageParts.size() > 1) {
@@ -54,9 +54,7 @@ public class DescriptionCommand extends Command {
             }
             write("You are now in multi-line mode.  Type \"done\" on an empty line to exit and save.\r\n");
             creeperSession.setGrabMultiLineInput(Optional.of(
-                    new CreeperEntry<UUID, Command>(gameManager.getMultiLineInputManager().createNewMultiLineInput(), this)));
-        } finally {
-           super.messageReceived(ctx, e);
-        }
+                    new CreeperEntry<>(gameManager.getMultiLineInputManager().createNewMultiLineInput(), descriptionCommand)));
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/GiveGoldCommand.java b/src/main/java/com/comandante/creeper/command/admin/GiveGoldCommand.java
index 081fa7bca893e797e7a854f75be9d210abcd676a..e054aca15ec521b6b83ac2602864dfd50854485b 100644
--- a/src/main/java/com/comandante/creeper/command/admin/GiveGoldCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/GiveGoldCommand.java
@@ -5,6 +5,7 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.collect.Sets;
+import org.apache.commons.lang.math.NumberUtils;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -17,7 +18,7 @@ public class GiveGoldCommand extends Command {
     final static List<String> validTriggers = Arrays.asList("givegold");
     final static String description = "Give Gold to a Player";
     final static String correctUsage = "givegold <player name> <amt>";
-    final static Set<PlayerRole> roles = Sets.newHashSet(PlayerRole.ADMIN);
+    final static Set<PlayerRole> roles = Sets.newHashSet();
 
 
     public GiveGoldCommand(GameManager gameManager) {
@@ -26,8 +27,7 @@ public class GiveGoldCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (!player.getPlayerName().equals("fibs")) {
                 write("This attempt to cheat has been logged.");
                 return;
@@ -35,7 +35,7 @@ public class GiveGoldCommand extends Command {
             if (originalMessageParts.size() > 2) {
                 String destinationPlayerName = originalMessageParts.get(1);
                 String amt = originalMessageParts.get(2);
-                if (!isInteger(amt)) {
+                if (!NumberUtils.isNumber(amt)) {
                     write("Third option to givegold needs to be an integer amount.");
                     return;
                 }
@@ -47,8 +47,6 @@ public class GiveGoldCommand extends Command {
                 playerByUsername.incrementGold(Integer.parseInt(amt));
                 write("The amount of " + amt + " gold has been placed into " + destinationPlayerName + "'s inventory.");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/admin/GiveHealthCommand.java b/src/main/java/com/comandante/creeper/command/admin/GiveHealthCommand.java
index 2c1f023cdda776837a419155084f90d7daba56b5..806fcff6d163a94be21f10fc9132e873b0127cdd 100644
--- a/src/main/java/com/comandante/creeper/command/admin/GiveHealthCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/GiveHealthCommand.java
@@ -1,10 +1,12 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.collect.Sets;
+import org.apache.commons.lang.math.NumberUtils;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -26,8 +28,7 @@ public class GiveHealthCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (!player.getPlayerName().equals("fibs")) {
                 write("This attempt to cheat has been logged.");
                 return;
@@ -35,7 +36,7 @@ public class GiveHealthCommand extends Command {
             if (originalMessageParts.size() > 2) {
                 String destinationPlayerName = originalMessageParts.get(1);
                 String amt = originalMessageParts.get(2);
-                if (!isInteger(amt)) {
+                if (!NumberUtils.isNumber(amt)) {
                     write("Third option to givehealth needs to be an integer amount.");
                     return;
                 }
@@ -47,8 +48,6 @@ public class GiveHealthCommand extends Command {
                 playerByUsername.incrementGold(Integer.parseInt(amt));
                 write("The amount of " + amt + " gold has been placed into " + destinationPlayerName + "'s inventory.");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/admin/InfoCommand.java b/src/main/java/com/comandante/creeper/command/admin/InfoCommand.java
index ada1145c298d7dce5e336374479ac13e60635e68..c9be087f9dd74c92240964178ef8a9945742380f 100644
--- a/src/main/java/com/comandante/creeper/command/admin/InfoCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/InfoCommand.java
@@ -23,11 +23,8 @@ public class InfoCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             write("roomId: " + currentRoom.getRoomId());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/admin/NotablesCommand.java b/src/main/java/com/comandante/creeper/command/admin/NotablesCommand.java
index cca81ea897c80b0604e1877efc2e0faf9aaf5715..c26a20f274f1463cae92345ec8f1a5c58aca7813 100644
--- a/src/main/java/com/comandante/creeper/command/admin/NotablesCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/NotablesCommand.java
@@ -1,9 +1,9 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
-import com.comandante.creeper.world.Area;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
@@ -22,13 +22,10 @@ public class NotablesCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             for (Map.Entry<String, String> notable : currentRoom.getNotables().entrySet()) {
                 write(notable.getKey() + " : " + notable.getValue() + "\r\n");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/NpcLocationCommand.java b/src/main/java/com/comandante/creeper/command/admin/NpcLocationCommand.java
index 56e5348c612644e0d7ed7219be8fef21ff517c7b..b9867f3afc895c5d83faab40267424d4b37ca571 100644
--- a/src/main/java/com/comandante/creeper/command/admin/NpcLocationCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/NpcLocationCommand.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.player.PlayerRole;
@@ -27,8 +28,7 @@ public class NpcLocationCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             Map<String, Set<Room>> npcMap = Maps.newTreeMap();
             Iterator<Map.Entry<String, Npc>> iterator = entityManager.getNpcs().entrySet().iterator();
             while (iterator.hasNext()) {
@@ -60,8 +60,6 @@ public class NpcLocationCommand extends Command {
                 }
             }
             write(resp.toString());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/ReloadNpcsCommand.java b/src/main/java/com/comandante/creeper/command/admin/ReloadNpcsCommand.java
old mode 100755
new mode 100644
index da6e0174366dba6b5248a8446886706f1f6d6680..bf4d515cfe501c54f73c9e2de382049b12999b54
--- a/src/main/java/com/comandante/creeper/command/admin/ReloadNpcsCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/ReloadNpcsCommand.java
@@ -2,13 +2,14 @@ package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.ConfigureNpc;
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.npc.NpcExporter;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
@@ -27,12 +28,13 @@ public class ReloadNpcsCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommandThreadSafe(ctx, e, ReloadNpcsCommand.class, () -> {
             gameManager.removeAllNpcs();
-            ConfigureNpc.configureAllNpcs(gameManager);
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+            try {
+                ConfigureNpc.configureAllNpcs(gameManager);
+            } catch (IOException ex) {
+                log.error("Unable to configure NPCS from disk.");
+            }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/admin/SaveWorldCommand.java b/src/main/java/com/comandante/creeper/command/admin/SaveWorldCommand.java
index 185f7cc6b5300bf83479a970e2290b1f2772e970..b4a2ca83627b12346d26731f807c6e907d9f312c 100644
--- a/src/main/java/com/comandante/creeper/command/admin/SaveWorldCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/SaveWorldCommand.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.collect.Sets;
@@ -24,12 +25,9 @@ public class SaveWorldCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommandThreadSafe(ctx, e, SaveWorldCommand.class, () -> {
             worldExporter.saveWorld();
             write("World saved.");
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/SpawnCommand.java b/src/main/java/com/comandante/creeper/command/admin/SpawnCommand.java
index e2a06a4a1c4bc386338de12f167a745756ee5b40..7d035384d59d7a17f6b3d98044de4afcdea9f716 100644
--- a/src/main/java/com/comandante/creeper/command/admin/SpawnCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/SpawnCommand.java
@@ -3,6 +3,7 @@ package com.comandante.creeper.command.admin;
 import com.comandante.creeper.Items.ItemType;
 import com.comandante.creeper.Items.Loot;
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.npc.NpcBuilder;
@@ -14,6 +15,7 @@ import com.google.common.collect.Sets;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
+import java.io.FileNotFoundException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
@@ -31,8 +33,7 @@ public class SpawnCommand  extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             List<Npc> npcsFromFile = NpcExporter.getNpcsFromFile(gameManager);
             if (originalMessageParts.size() == 1) {
                 write(getHeader());
@@ -56,9 +57,7 @@ public class SpawnCommand  extends Command {
                 }
                 write("No npc found with name: " + targetNpc + "\r\n");
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 
     public String getHeader() {
diff --git a/src/main/java/com/comandante/creeper/command/admin/SystemInfo.java b/src/main/java/com/comandante/creeper/command/admin/SystemInfo.java
old mode 100755
new mode 100644
index 19a45f77d72853987038e2179bf076415c70a47c..80875f16296d6fa2d83dd0a9775dc9fca53cf30e
--- a/src/main/java/com/comandante/creeper/command/admin/SystemInfo.java
+++ b/src/main/java/com/comandante/creeper/command/admin/SystemInfo.java
@@ -2,6 +2,7 @@ package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.Main;
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.comandante.creeper.server.Color;
@@ -29,8 +30,7 @@ public class SystemInfo extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             String os_name = System.getProperty("os.name", "OS_NAME");
             String os_version = System.getProperty("os.version", "OS_VERSION");
             String java_version = System.getProperty("java.version", "JAVA_VERSION");
@@ -69,9 +69,7 @@ public class SystemInfo extends Command {
                     .append(Color.RESET)
                     .append(Main.getCreeperVersion())
                     .append("\r\n").toString());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 
     public static String getDurationBreakdown(long millis) {
diff --git a/src/main/java/com/comandante/creeper/command/admin/TagRoomCommand.java b/src/main/java/com/comandante/creeper/command/admin/TagRoomCommand.java
index 72676672f34ddb042a5ff028720ac1d3cc7790ab..9094d70d2dc13c58b57d1eda127bd1156f741521 100644
--- a/src/main/java/com/comandante/creeper/command/admin/TagRoomCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/TagRoomCommand.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.collect.Sets;
@@ -25,14 +26,11 @@ public class TagRoomCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             originalMessageParts.remove(0);
             if (originalMessageParts.get(0).equalsIgnoreCase("list")) {
                 StringBuilder sb = new StringBuilder();
-                Iterator<String> iterator = currentRoom.getRoomTags().iterator();
-                while (iterator.hasNext()) {
-                    String tag = iterator.next();
+                for (String tag : currentRoom.getRoomTags()) {
                     sb.append(tag).append("\n");
                 }
                 write("tag\n---");
@@ -41,8 +39,6 @@ public class TagRoomCommand extends Command {
             }
             currentRoom.addTag(originalMessageParts.get(0));
             write(String.format("tagged world with tag: \"%s\".", originalMessageParts.get(0)));
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/TeleportCommand.java b/src/main/java/com/comandante/creeper/command/admin/TeleportCommand.java
index 14d64d9c5d5514c5e6677e57815051de8de0e3b8..a0ba7ce2784cdc177f23ddcb4119a18cf2cb3f2f 100644
--- a/src/main/java/com/comandante/creeper/command/admin/TeleportCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/TeleportCommand.java
@@ -31,8 +31,7 @@ public class TeleportCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             if (originalMessageParts.size() <= 1) {
                 return;
             }
@@ -58,7 +57,7 @@ public class TeleportCommand extends Command {
                 if (next.getValue().getPlayerName().equals(desiredId)) {
                     Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(next.getValue()).get();
                     Integer destinationRoomId = playerCurrentRoom.getRoomId();
-                    PlayerMovement playerMovement = new PlayerMovement(player, gameManager.getRoomManager().getPlayerCurrentRoom(player).get().getRoomId(), playerCurrentRoom.getRoomId(), null, "vanished into the heavens.", "");
+                    PlayerMovement playerMovement = new PlayerMovement(player, gameManager.getRoomManager().getPlayerCurrentRoom(player).get().getRoomId(), playerCurrentRoom.getRoomId(), "vanished into the heavens.", "");
                     gameManager.writeToRoom(destinationRoomId, teleportMessage);
                     channelUtils.write(playerId, teleportMessage);
                     player.movePlayer(playerMovement);
@@ -66,11 +65,11 @@ public class TeleportCommand extends Command {
                     return;
                 }
             }
-            Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRooms();
+            Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRoomsIterator();
             while (rooms.hasNext()) {
                 Map.Entry<Integer, Room> next = rooms.next();
                 if (Integer.toString(next.getKey()).equals(desiredId)) {
-                    PlayerMovement playerMovement = new PlayerMovement(player, gameManager.getRoomManager().getPlayerCurrentRoom(player).get().getRoomId(), Integer.parseInt(desiredId), null, "vanished into the heavens.", "");
+                    PlayerMovement playerMovement = new PlayerMovement(player, gameManager.getRoomManager().getPlayerCurrentRoom(player).get().getRoomId(), Integer.parseInt(desiredId), "vanished into the heavens.", "");
                     gameManager.writeToRoom(Integer.parseInt(desiredId), teleportMessage);
                     channelUtils.write(playerId, teleportMessage);
                     player.movePlayer(playerMovement);
@@ -78,8 +77,6 @@ public class TeleportCommand extends Command {
                     return;
                 }
             }
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/command/admin/TitleCommand.java b/src/main/java/com/comandante/creeper/command/admin/TitleCommand.java
index 088f26dc084396908f452051ac96b205ee645d04..81078c08233825778ccc447aded31fd7238e5eb7 100644
--- a/src/main/java/com/comandante/creeper/command/admin/TitleCommand.java
+++ b/src/main/java/com/comandante/creeper/command/admin/TitleCommand.java
@@ -1,6 +1,7 @@
 package com.comandante.creeper.command.admin;
 
 import com.comandante.creeper.command.Command;
+import com.comandante.creeper.command.CommandRunnable;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.PlayerRole;
 import com.google.common.base.Joiner;
@@ -26,13 +27,10 @@ public class TitleCommand extends Command {
 
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
+        execCommand(ctx, e, () -> {
             originalMessageParts.remove(0);
             currentRoom.setRoomTitle(Joiner.on(" ").join(originalMessageParts));
             write("Titled saved.");
-        } finally {
-            super.messageReceived(ctx, e);
-        }
+        });
     }
 }
diff --git a/src/main/java/com/comandante/creeper/command/admin/UsersCommand.java b/src/main/java/com/comandante/creeper/command/admin/UsersCommand.java
deleted file mode 100755
index 18e629efd66b2be39063fdf754aad74d98924e20..0000000000000000000000000000000000000000
--- a/src/main/java/com/comandante/creeper/command/admin/UsersCommand.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package com.comandante.creeper.command.admin;
-
-import com.comandante.creeper.command.Command;
-import com.comandante.creeper.managers.GameManager;
-import com.comandante.creeper.player.Player;
-import com.comandante.creeper.player.PlayerRole;
-import com.google.common.collect.Sets;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.MessageEvent;
-import org.nocrala.tools.texttablefmt.BorderStyle;
-import org.nocrala.tools.texttablefmt.ShownBorders;
-import org.nocrala.tools.texttablefmt.Table;
-
-import java.net.InetSocketAddress;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-public class UsersCommand extends Command {
-
-    final static List<String> validTriggers = Arrays.asList("users");
-    final static String description = "Display extended inforation about who is logged in.";
-    final static String correctUsage = "users";
-    final static Set<PlayerRole> roles = Sets.newHashSet(PlayerRole.ADMIN);
-
-    public UsersCommand(GameManager gameManager) {
-        super(gameManager, validTriggers, description, correctUsage, roles);
-    }
-
-    @Override
-    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-        configure(e);
-        try {
-            Table t = new Table(4, BorderStyle.BLANKS,
-                    ShownBorders.NONE);
-            t.setColumnWidth(0, 14, 24);
-            t.setColumnWidth(1, 18, 18);
-            t.setColumnWidth(2, 21, 21);
-            t.addCell("Player");
-            t.addCell("IP");
-            t.addCell("Logged in since");
-            t.addCell("Idle");
-            Set<Player> allPlayers = gameManager.getAllPlayers();
-            for (Player allPlayer : allPlayers) {
-                t.addCell(allPlayer.getPlayerName());
-
-                InetSocketAddress remoteAddress = (InetSocketAddress) allPlayer.getChannel().getRemoteAddress();
-                String remoteUsersHost = remoteAddress.getHostString();
-                t.addCell(remoteUsersHost);
-
-                DateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
-                String loginTime = format.format(new Date(playerManager.getSessionManager().getSession(allPlayer.getPlayerId()).getInitialLoginTime()));
-                t.addCell(loginTime);
-
-                long lastActivity = playerManager.getSessionManager().getSession(allPlayer.getPlayerId()).getLastActivity();
-                long idleTimeMs = System.currentTimeMillis() - lastActivity;
-                String idleTime = String.format("%d min, %d sec",
-                        TimeUnit.MILLISECONDS.toMinutes(idleTimeMs),
-                        TimeUnit.MILLISECONDS.toSeconds(idleTimeMs) -
-                                TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(idleTimeMs))
-                );
-                t.addCell(idleTime);
-            }
-            write(t.render());
-        } finally {
-            super.messageReceived(ctx, e);
-        }
-    }
-}
diff --git a/src/main/java/com/comandante/creeper/entity/EntityManager.java b/src/main/java/com/comandante/creeper/entity/EntityManager.java
index 5c4cccddcab24b64b4b842cda823cedf20cc6289..ff637721337ad9bb7d048efab38e0b07b9496984 100644
--- a/src/main/java/com/comandante/creeper/entity/EntityManager.java
+++ b/src/main/java/com/comandante/creeper/entity/EntityManager.java
@@ -25,6 +25,7 @@ import static com.codahale.metrics.MetricRegistry.name;
 
 public class EntityManager {
 
+    private static final Logger log = Logger.getLogger(EntityManager.class);
     private final ConcurrentHashMap<String, Npc> npcs = new ConcurrentHashMap<>();
     private final HTreeMap<String, Item> items;
     private final HTreeMap<String, Effect> effects;
@@ -32,7 +33,6 @@ public class EntityManager {
     private final ExecutorService mainTickExecutorService = Executors.newFixedThreadPool(50);
     private final RoomManager roomManager;
     private final PlayerManager playerManager;
-    private static final Logger log = Logger.getLogger(EntityManager.class);
 
     public EntityManager(RoomManager roomManager, PlayerManager playerManager, DB db) {
         this.roomManager = roomManager;
@@ -148,7 +148,7 @@ public class EntityManager {
             while (true) {
                 try {
                     final com.codahale.metrics.Timer.Context context = ticktime.time();
-                    Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRooms();
+                    Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRoomsIterator();
                     while (rooms.hasNext()) {
                         Map.Entry<Integer, Room> next = rooms.next();
                         mainTickExecutorService.submit(next.getValue());
diff --git a/src/main/java/com/comandante/creeper/managers/GameManager.java b/src/main/java/com/comandante/creeper/managers/GameManager.java
old mode 100755
new mode 100644
index 215f741d70c0e6410a7e49ef65a1f532551798ae..7583b864b407895fbe3b955fb344f116039d29ff
--- a/src/main/java/com/comandante/creeper/managers/GameManager.java
+++ b/src/main/java/com/comandante/creeper/managers/GameManager.java
@@ -5,6 +5,7 @@ import com.comandante.creeper.CreeperConfiguration;
 import com.comandante.creeper.IrcBotService;
 import com.comandante.creeper.Items.*;
 import com.comandante.creeper.Main;
+import com.comandante.creeper.SingleThreadedCreeperEventProcessor;
 import com.comandante.creeper.bot.BotCommandFactory;
 import com.comandante.creeper.bot.BotCommandManager;
 import com.comandante.creeper.entity.CreeperEntity;
@@ -13,7 +14,7 @@ import com.comandante.creeper.merchant.Merchant;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.npc.NpcMover;
 import com.comandante.creeper.player.*;
-import com.comandante.creeper.server.ChannelUtils;
+import com.comandante.creeper.server.ChannelCommunicationUtils;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.server.GossipCache;
 import com.comandante.creeper.server.MultiLineInputManager;
@@ -24,7 +25,6 @@ import com.comandante.creeper.stat.Stats;
 import com.comandante.creeper.stat.StatsBuilder;
 import com.comandante.creeper.world.*;
 import com.google.api.client.util.Lists;
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Interner;
 import com.google.common.collect.Interners;
@@ -37,16 +37,18 @@ import org.nocrala.tools.texttablefmt.Table;
 
 import java.text.NumberFormat;
 import java.util.*;
+import java.util.concurrent.ArrayBlockingQueue;
 
 import static com.comandante.creeper.server.Color.*;
 
 public class GameManager {
 
+    public static final Integer LOBBY_ID = 1;
+    private static final Logger log = Logger.getLogger(GameManager.class);
     public static String LOGO = "Creeper.";
-
     private final RoomManager roomManager;
     private final PlayerManager playerManager;
-    private final ChannelUtils channelUtils;
+    private final ChannelCommunicationUtils channelUtils;
     private final NewUserRegistrationManager newUserRegistrationManager;
     private final EntityManager entityManager;
     private final ItemDecayManager itemDecayManager;
@@ -63,12 +65,12 @@ public class GameManager {
     private final StatsModifierFactory statsModifierFactory;
     private final GossipCache gossipCache;
     private final Interner<String> interner = Interners.newWeakInterner();
-    private static final Logger log = Logger.getLogger(GameManager.class);
     private final TimeTracker timeTracker;
     private final ItemUseHandler itemUseHandler;
     private final NpcMover npcMover;
+    private final SingleThreadedCreeperEventProcessor eventProcessor = new SingleThreadedCreeperEventProcessor(new ArrayBlockingQueue<>(100000));
 
-    public GameManager(CreeperConfiguration creeperConfiguration, RoomManager roomManager, PlayerManager playerManager, EntityManager entityManager, MapsManager mapsManager, ChannelUtils channelUtils) {
+    public GameManager(CreeperConfiguration creeperConfiguration, RoomManager roomManager, PlayerManager playerManager, EntityManager entityManager, MapsManager mapsManager, ChannelCommunicationUtils channelUtils) {
         this.roomManager = roomManager;
         this.playerManager = playerManager;
         this.entityManager = entityManager;
@@ -92,6 +94,7 @@ public class GameManager {
         this.entityManager.addEntity(itemDecayManager);
         this.itemUseHandler = new ItemUseHandler(this);
         this.npcMover = new NpcMover(this);
+        this.eventProcessor.startAsync();
     }
 
     public NpcMover getNpcMover() {
@@ -154,10 +157,6 @@ public class GameManager {
         return newUserRegistrationManager;
     }
 
-    public ChannelUtils getChannelUtils() {
-        return channelUtils;
-    }
-
     public ItemDecayManager getItemDecayManager() {
         return itemDecayManager;
     }
@@ -166,23 +165,36 @@ public class GameManager {
         return entityManager;
     }
 
-    public RoomManager getRoomManager() {
-        return roomManager;
+    public TimeTracker getTimeTracker() {
+        return timeTracker;
     }
 
-    public PlayerManager getPlayerManager() {
-        return playerManager;
+    public SingleThreadedCreeperEventProcessor getEventProcessor() {
+        return eventProcessor;
     }
 
-    public TimeTracker getTimeTracker() {
-        return timeTracker;
+    public void placePlayerInLobby(Player player) {
+        Room room = roomManager.getRoom(LOBBY_ID);
+        room.addPresentPlayer(player.getPlayerId());
+        player.setCurrentRoom(room);
+        for (Player next : roomManager.getPresentPlayers(room)) {
+            if (next.getPlayerId().equals(player.getPlayerId())) {
+                continue;
+            }
+            channelUtils.write(next.getPlayerId(), player.getPlayerName() + " arrived.", true);
+        }
     }
 
-    public static final Integer LOBBY_ID = 1;
+    public void announceConnect(String userName) {
+        Set<Player> allPlayers = getAllPlayers();
+        for (Player p : allPlayers) {
+            getChannelUtils().write(p.getPlayerId(), Color.GREEN + userName + " has connected." + Color.RESET + "\r\n", true);
+        }
+    }
 
     public Set<Player> getAllPlayers() {
         ImmutableSet.Builder<Player> builder = ImmutableSet.builder();
-        Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRoomsIterator();
         while (rooms.hasNext()) {
             Map.Entry<Integer, Room> next = rooms.next();
             Room room = next.getValue();
@@ -194,23 +206,75 @@ public class GameManager {
         return builder.build();
     }
 
-    public void placePlayerInLobby(Player player) {
-        Room room = roomManager.getRoom(LOBBY_ID);
-        room.addPresentPlayer(player.getPlayerId());
-        player.setCurrentRoom(room);
-        for (Player next : roomManager.getPresentPlayers(room)) {
-            if (next.getPlayerId().equals(player.getPlayerId())) {
+    public ChannelCommunicationUtils getChannelUtils() {
+        return channelUtils;
+    }
+
+    public void currentRoomLogic(String playerId) {
+        Player player = playerManager.getPlayer(playerId);
+        final Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(player).get();
+        currentRoomLogic(playerId, playerCurrentRoom);
+    }
+
+    public void currentRoomLogic(String playerId, Room playerCurrentRoom) {
+        Player player = playerManager.getPlayer(playerId);
+        StringBuilder sb = new StringBuilder();
+        sb.append(Color.BOLD_ON + Color.GREEN);
+        sb.append(playerCurrentRoom.getRoomTitle());
+        sb.append(RESET);
+        sb.append("\r\n\r\n");
+        sb.append(WordUtils.wrap(playerCurrentRoom.getRoomDescription(), 80, "\r\n", true)).append("\r\n").append("\r\n");
+        String auto_map = player.getPlayerSetting("auto_map");
+        if (playerCurrentRoom.getMapData().isPresent() && auto_map != null) {
+            int i = Integer.parseInt(auto_map);
+            sb.append(mapsManager.drawMap(playerCurrentRoom.getRoomId(), new Coords(i, i))).append("\r\n");
+        }
+        sb.append(getExits(playerCurrentRoom, player)).append("\r\n");
+
+        Set<Merchant> merchants = playerCurrentRoom.getMerchants();
+        for (Merchant merchant : merchants) {
+            sb.append(merchant.getColorName()).append(" is here.").append(RESET).append("\r\n");
+        }
+        for (Player searchPlayer : roomManager.getPresentPlayers(playerCurrentRoom)) {
+            if (searchPlayer.getPlayerId().equals(player.getPlayerId())) {
                 continue;
             }
-            channelUtils.write(next.getPlayerId(), player.getPlayerName() + " arrived.", true);
+            sb.append(searchPlayer.getPlayerName()).append(" is here.").append(RESET).append("\r\n");
         }
-    }
 
-    public void announceConnect(String userName) {
-        Set<Player> allPlayers = getAllPlayers();
-        for (Player p : allPlayers) {
-            getChannelUtils().write(p.getPlayerId(), Color.GREEN + userName + " has connected." + Color.RESET + "\r\n", true);
+        for (String itemId : playerCurrentRoom.getItemIds()) {
+            Item itemEntity = entityManager.getItemEntity(itemId);
+            if (itemEntity == null) {
+                playerCurrentRoom.removePresentItem(itemId);
+                continue;
+            }
+            sb.append("   ").append(entityManager.getItemEntity(itemId).getRestingName()).append("\r\n");
         }
+
+        List<String> npcs = Lists.newArrayList();
+        for (String npcId : playerCurrentRoom.getNpcIds()) {
+            StringBuilder sbb = new StringBuilder();
+            Npc npcEntity = entityManager.getNpcEntity(npcId);
+            if (Main.vowels.contains(Character.toLowerCase(npcEntity.getName().charAt(0)))) {
+                sbb.append("an ");
+            } else {
+                sbb.append("a ");
+            }
+            sbb.append(npcEntity.getColorName()).append(" is here.\r\n");
+            npcs.add(sbb.toString());
+        }
+        Collections.sort(npcs, String.CASE_INSENSITIVE_ORDER);
+        for (String s : npcs) {
+            sb.append(s);
+        }
+        String msg = null;
+        if (sb.toString().substring(sb.toString().length() - 2).equals("\r\n")) {
+            CharSequence charSequence = sb.toString().subSequence(0, sb.toString().length() - 2);
+            msg = charSequence.toString();
+        } else {
+            msg = sb.toString();
+        }
+        channelUtils.write(player.getPlayerId(), msg);
     }
 
     private String getExits(Room room, Player player) {
@@ -299,78 +363,28 @@ public class GameManager {
         return fin;
     }
 
-    public void currentRoomLogic(String playerId) {
-        Player player = playerManager.getPlayer(playerId);
-        final Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(player).get();
-        currentRoomLogic(playerId, playerCurrentRoom);
+    public void placeItemInRoom(Integer roomId, String itemId) {
+        roomManager.getRoom(roomId).addPresentItem(entityManager.getItemEntity(itemId).getItemId());
     }
 
-    public void currentRoomLogic(String playerId, Room playerCurrentRoom) {
-        Player player = playerManager.getPlayer(playerId);
-        StringBuilder sb = new StringBuilder();
-        sb.append(Color.BOLD_ON + Color.GREEN);
-        sb.append(playerCurrentRoom.getRoomTitle());
-        sb.append(RESET);
-        sb.append("\r\n\r\n");
-        sb.append(WordUtils.wrap(playerCurrentRoom.getRoomDescription(), 80, "\r\n", true)).append("\r\n").append("\r\n");
-        String auto_map = player.getPlayerSetting("auto_map");
-        if (playerCurrentRoom.getMapData().isPresent() && auto_map != null) {
-            int i = Integer.parseInt(auto_map);
-            sb.append(mapsManager.drawMap(playerCurrentRoom.getRoomId(), new Coords(i, i))).append("\r\n");
-        }
-        sb.append(getExits(playerCurrentRoom, player)).append("\r\n");
-
-        Set<Merchant> merchants = playerCurrentRoom.getMerchants();
-        for (Merchant merchant : merchants) {
-            sb.append(merchant.getColorName()).append(" is here.").append(RESET).append("\r\n");
-        }
-        for (Player searchPlayer : roomManager.getPresentPlayers(playerCurrentRoom)) {
-            if (searchPlayer.getPlayerId().equals(player.getPlayerId())) {
-                continue;
-            }
-            sb.append(searchPlayer.getPlayerName()).append(" is here.").append(RESET).append("\r\n");
-        }
-
-        for (String itemId : playerCurrentRoom.getItemIds()) {
-            Item itemEntity = entityManager.getItemEntity(itemId);
-            if (itemEntity == null) {
-                playerCurrentRoom.removePresentItem(itemId);
-                continue;
-            }
-            sb.append("   ").append(entityManager.getItemEntity(itemId).getRestingName()).append("\r\n");
-        }
-
-        List<String> npcs = Lists.newArrayList();
-        for (String npcId : playerCurrentRoom.getNpcIds()) {
-            StringBuilder sbb = new StringBuilder();
-            Npc npcEntity = entityManager.getNpcEntity(npcId);
-            if (Main.vowels.contains(Character.toLowerCase(npcEntity.getName().charAt(0)))) {
-                sbb.append("an ");
-            } else {
-                sbb.append("a ");
+    public boolean acquireItemFromRoom(Player player, String itemId) {
+        synchronized (interner.intern(itemId)) {
+            Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(player).get();
+            if (playerCurrentRoom.getItemIds().contains(itemId)) {
+                if (acquireItem(player, itemId)) {
+                    playerCurrentRoom.getItemIds().remove(itemId);
+                    return true;
+                }
             }
-            sbb.append(npcEntity.getColorName()).append(" is here.\r\n");
-            npcs.add(sbb.toString());
-        }
-        Collections.sort(npcs, String.CASE_INSENSITIVE_ORDER);
-        for (String s : npcs) {
-            sb.append(s);
         }
-        String msg = null;
-        if (sb.toString().substring(sb.toString().length() - 2).equals("\r\n")) {
-            CharSequence charSequence = sb.toString().subSequence(0, sb.toString().length() - 2);
-            msg = charSequence.toString();
-        } else {
-            msg = sb.toString();
-        }
-        channelUtils.write(player.getPlayerId(), msg);
+        return false;
     }
 
-    public void placeItemInRoom(Integer roomId, String itemId) {
-        roomManager.getRoom(roomId).addPresentItem(entityManager.getItemEntity(itemId).getItemId());
+    public boolean acquireItem(Player player, String itemId) {
+        return acquireItem(player, itemId, false);
     }
 
-    public boolean acquireItem(Player player, String itemId) {
+    public boolean acquireItem(Player player, String itemId, boolean isFromLoot) {
         synchronized (interner.intern(itemId)) {
             Stats playerStatsWithEquipmentAndLevel = player.getPlayerStatsWithEquipmentAndLevel();
             if (player.getInventory().size() < playerStatsWithEquipmentAndLevel.getInventorySize()) {
@@ -380,23 +394,15 @@ public class GameManager {
                 entityManager.saveItem(itemEntity);
                 return true;
             } else {
+                Item itemEntity = entityManager.getItemEntity(itemId);
                 channelUtils.write(player.getPlayerId(), "Your inventory is full, drop some items to free up room.\r\n");
-                return false;
-            }
-        }
-    }
-
-    public boolean acquireItemFromRoom(Player player, String itemId) {
-        synchronized (interner.intern(itemId)) {
-            Room playerCurrentRoom = roomManager.getPlayerCurrentRoom(player).get();
-            if (playerCurrentRoom.getItemIds().contains(itemId)) {
-                if (acquireItem(player, itemId)) {
-                    playerCurrentRoom.getItemIds().remove(itemId);
-                    return true;
+                if (isFromLoot) {
+                    player.getCurrentRoom().addPresentItem(itemId);
+                    roomSay(player.getCurrentRoom().getRoomId(), player.getPlayerName() + " dropped " + itemEntity.getItemName(), player.getPlayerId() + "\r\n");
                 }
+                return false;
             }
         }
-        return false;
     }
 
     public void roomSay(Integer roomId, String message, String sourcePlayerId) {
@@ -410,10 +416,13 @@ public class GameManager {
         }
     }
 
-    public String getLookString(Npc npc) {
+    public String getLookString(Npc npc, long playerLevel) {
         StringBuilder sb = new StringBuilder();
         // passing an empty createState because of the "difference calculation"
         sb.append(Color.MAGENTA + "-+=[ " + Color.RESET).append(npc.getColorName()).append(Color.MAGENTA + " ]=+- " + Color.RESET).append("\r\n");
+        sb.append("Level ").append(Levels.getLevel(npc.getStats().getExperience())).append(" ")
+                .append(npc.getLevelColor((int) playerLevel).getColor())
+                .append(" [").append(npc.getTemperament().getFriendlyFormat()).append("]").append("\r\n");
         sb.append(Color.MAGENTA + "Stats--------------------------------" + Color.RESET).append("\r\n");
         sb.append(buildLookString(npc.getColorName(), npc.getStats(), new StatsBuilder().createStats())).append("\r\n");
         if (npc.getEffects() != null && npc.getEffects().size() > 0) {
@@ -423,45 +432,6 @@ public class GameManager {
         return sb.toString();
     }
 
-    public String buldEffectsString(Npc npc) {
-        return renderEffectsString(npc.getEffects());
-
-    }
-
-    public String renderEffectsString(List<Effect> effects) {
-        org.nocrala.tools.texttablefmt.Table t = new org.nocrala.tools.texttablefmt.Table(2, BorderStyle.CLASSIC_COMPATIBLE,
-                ShownBorders.NONE);
-
-        t.setColumnWidth(0, 16, 20);
-        // t.setColumnWidth(1, 10, 13);
-
-        int i = 1;
-        for (Effect effect : effects) {
-            int percent = 100 - (int) ((effect.getEffectApplications() * 100.0f) / effect.getMaxEffectApplications());
-            t.addCell(drawProgressBar(percent));
-            t.addCell(effect.getEffectName());
-            i++;
-        }
-        return t.render();
-    }
-
-    public String renderCoolDownString(Set<CoolDown> coolDowns) {
-        org.nocrala.tools.texttablefmt.Table t = new org.nocrala.tools.texttablefmt.Table(2, BorderStyle.CLASSIC_COMPATIBLE,
-                ShownBorders.NONE);
-
-        t.setColumnWidth(0, 16, 20);
-        // t.setColumnWidth(1, 10, 13);
-
-        int i = 1;
-        for (CoolDown coolDown : coolDowns) {
-            int percent = 100 - (int) (((coolDown.getOriginalNumberOfTicks() - coolDown.getNumberOfTicks()) * 100.0f) / coolDown.getOriginalNumberOfTicks());
-            t.addCell(drawProgressBar(percent));
-            t.addCell(coolDown.getName());
-            i++;
-        }
-        return t.render();
-    }
-
     public String buildLookString(String name, Stats stats, Stats diff) {
         StringBuilder returnString = new StringBuilder();
         Table t = new Table(3, BorderStyle.CLASSIC_COMPATIBLE,
@@ -562,10 +532,72 @@ public class GameManager {
         return returnString.toString();
     }
 
+    public String buldEffectsString(Npc npc) {
+        return renderEffectsString(npc.getEffects());
+
+    }
+
     private String getFormattedNumber(Long longval) {
         return NumberFormat.getNumberInstance(Locale.US).format(longval);
     }
 
+    public String renderEffectsString(List<Effect> effects) {
+        Table t = new Table(2, BorderStyle.CLASSIC_COMPATIBLE,
+                ShownBorders.NONE);
+
+        t.setColumnWidth(0, 16, 20);
+        // t.setColumnWidth(1, 10, 13);
+
+        int i = 1;
+        for (Effect effect : effects) {
+            int percent = 100 - (int) ((effect.getEffectApplications() * 100.0f) / effect.getMaxEffectApplications());
+            t.addCell(drawProgressBar(percent));
+            t.addCell(effect.getEffectName());
+            i++;
+        }
+        return t.render();
+    }
+
+    public String drawProgressBar(int pct) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        int numberOfProgressBarNotches = getNumberOfProgressBarNotches(pct);
+        for (int i = 0; i < numberOfProgressBarNotches; i++) {
+            sb.append("+");
+        }
+        for (int i = numberOfProgressBarNotches; i < 10; i++) {
+            sb.append(" ");
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public int getNumberOfProgressBarNotches(int y) {
+        int x = (int) (Math.round(y / 10.0) * 10);
+        String str = Integer.toString(x);
+        if (str.length() > 1) {
+            str = str.substring(0, str.length() - 1);
+        }
+        return Integer.parseInt(str);
+    }
+
+    public String renderCoolDownString(Set<CoolDown> coolDowns) {
+        Table t = new Table(2, BorderStyle.CLASSIC_COMPATIBLE,
+                ShownBorders.NONE);
+
+        t.setColumnWidth(0, 16, 20);
+        // t.setColumnWidth(1, 10, 13);
+
+        int i = 1;
+        for (CoolDown coolDown : coolDowns) {
+            int percent = 100 - (int) (((coolDown.getOriginalNumberOfTicks() - coolDown.getNumberOfTicks()) * 100.0f) / coolDown.getOriginalNumberOfTicks());
+            t.addCell(drawProgressBar(percent));
+            t.addCell(coolDown.getName());
+            i++;
+        }
+        return t.render();
+    }
+
     public void writeToPlayerCurrentRoom(String playerId, String message) {
         if (playerManager.getSessionManager().getSession(playerId).getGrabMultiLineInput().isPresent()) {
             return;
@@ -616,21 +648,29 @@ public class GameManager {
             long amount = damageEntry.getValue();
             double pct = (double) amount / totalDamageDone;
             if (pct >= .90) {
-                damagePcts.put(playerId, npc.getPctOFExperience(1, Levels.getLevel(playerMetadata.getStats().getExperience())));
+                damagePcts.put(playerId, (double) 1);
             } else if (pct >= 0.25) {
-                damagePcts.put(playerId, npc.getPctOFExperience(.8, Levels.getLevel(playerMetadata.getStats().getExperience())));
+                damagePcts.put(playerId, .8);
             } else if (pct >= 0.10) {
-                damagePcts.put(playerId, npc.getPctOFExperience(.5, Levels.getLevel(playerMetadata.getStats().getExperience())));
+                damagePcts.put(playerId, .5);
             } else {
-                damagePcts.put(playerId, npc.getPctOFExperience(.25, Levels.getLevel(playerMetadata.getStats().getExperience())));
+                damagePcts.put(playerId, .25);
             }
         }
         return damagePcts;
     }
 
+    public PlayerManager getPlayerManager() {
+        return playerManager;
+    }
+
+    public RoomManager getRoomManager() {
+        return roomManager;
+    }
+
     public synchronized void removeAllNpcs() {
         for (Npc npc : entityManager.getNpcs().values()) {
-            Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRooms();
+            Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRoomsIterator();
             while (rooms.hasNext()) {
                 Map.Entry<Integer, Room> next = rooms.next();
                 next.getValue().removePresentNpc(npc.getEntityId());
@@ -645,7 +685,6 @@ public class GameManager {
         }
     }
 
-
     public String buildPrompt(String playerId) {
         Player player = playerManager.getPlayer(playerId);
         boolean isFight = player.isActiveFights();
@@ -678,41 +717,23 @@ public class GameManager {
             sb.append(Color.RED + " ! " + Color.RESET);
         }
         if (player.isActiveCoolDown()) {
-            sb.append(" ");
             if (player.isActive(CoolDownType.DEATH)) {
+                sb.append(" ");
                 sb.append(Color.RED + "D" + Color.RESET);
             }
             if (player.isActiveForageCoolDown()) {
+                sb.append(" ");
                 sb.append(Color.GREEN + "F" + Color.RESET);
             }
         }
+        if (player.isActiveAlertNpcStatus()) {
+            sb.append(" ");
+            sb.append(Color.RED + "ALERT" + Color.RESET);
+        }
         sb.append(Color.BOLD_ON + Color.WHITE);
         sb.append("] ");
         sb.append(Color.RESET);
         return sb.toString();
     }
-
-    public String drawProgressBar(int pct) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[");
-        int numberOfProgressBarNotches = getNumberOfProgressBarNotches(pct);
-        for (int i = 0; i < numberOfProgressBarNotches; i++) {
-            sb.append("+");
-        }
-        for (int i = numberOfProgressBarNotches; i < 10; i++) {
-            sb.append(" ");
-        }
-        sb.append("]");
-        return sb.toString();
-    }
-
-    public int getNumberOfProgressBarNotches(int y) {
-        int x = (int) (Math.round(y / 10.0) * 10);
-        String str = Integer.toString(x);
-        if (str.length() > 1) {
-            str = str.substring(0, str.length() - 1);
-        }
-        return Integer.parseInt(str);
-    }
 }
 
diff --git a/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java b/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java
index b2ef99bb5c92ffecbb50271cbb3537e74f79e166..ed068573b22ab601057d6c1833ac6b014ff4b073 100644
--- a/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java
+++ b/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java
@@ -8,6 +8,7 @@ import com.comandante.creeper.player.PlayerRole;
 import com.comandante.creeper.player.PlayerStats;
 import com.comandante.creeper.server.CreeperSession;
 import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -46,7 +47,7 @@ public class NewUserRegistrationManager {
             newUserRegistrationFlow(session, e);
             return false;
         }
-        session.setUsername(Optional.of(username));
+        session.setUsername(java.util.Optional.of(username));
         return true;
     }
 
@@ -63,7 +64,7 @@ public class NewUserRegistrationManager {
             return;
         }
         session.setPassword(Optional.of(password));
-        PlayerMetadata playerMetadata = new PlayerMetadata(session.getUsername().get(), session.getPassword().get(), Main.createPlayerId(session.getUsername().get()), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), new String[0], 0);
+        PlayerMetadata playerMetadata = new PlayerMetadata(session.getUsername().get(), session.getPassword().get(), Main.createPlayerId(session.getUsername().get()), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), new String[0], 0, new String[0], Maps.newHashMap());
         playerManager.savePlayerMetadata(playerMetadata);
         e.getChannel().write("User created.\r\n");
         session.setState(CreeperSession.State.newUserRegCompleted);
diff --git a/src/main/java/com/comandante/creeper/managers/SentryManager.java b/src/main/java/com/comandante/creeper/managers/SentryManager.java
index 1c4a80f431d7e9fc808a39ce4038665a6b106269..5e9d0d971d6a94f7141f72cb93f19f63c184bcf0 100644
--- a/src/main/java/com/comandante/creeper/managers/SentryManager.java
+++ b/src/main/java/com/comandante/creeper/managers/SentryManager.java
@@ -9,20 +9,21 @@ import net.kencochrane.raven.event.interfaces.ExceptionInterface;
 
 public class SentryManager {
 
-    private static Raven raven = RavenFactory.ravenInstance(new Dsn("https://f6888b8b68384ae8a6e5809f8fb08a6d:e2e3dbaaaa8d40639c87d7b16a1539f9@app.getsentry.com/47336"));
+   // private static Raven raven = RavenFactory.ravenInstance(new Dsn("https://f6888b8b68384ae8a6e5809f8fb08a6d:e2e3dbaaaa8d40639c87d7b16a1539f9@app.getsentry.com/47336"));
 
     public static void logSentry(Class c, Exception e, String msg) {
-        EventBuilder eventBuilder = new EventBuilder()
+      /*  EventBuilder eventBuilder = new EventBuilder()
                 .setMessage(msg)
                 .setLevel(Event.Level.ERROR)
                 .setLogger(c.getName())
                 .addSentryInterface(new ExceptionInterface(e));
 
         raven.runBuilderHelpers(eventBuilder);
-        raven.sendEvent(eventBuilder.build());
+        raven.sendEvent(eventBuilder.build());*/
     }
 
     public static void logSentry(Class c, Throwable e, String msg) {
+        /*
         EventBuilder eventBuilder = new EventBuilder()
                 .setMessage(msg)
                 .setLevel(Event.Level.ERROR)
@@ -30,6 +31,6 @@ public class SentryManager {
                 .addSentryInterface(new ExceptionInterface(e));
 
         raven.runBuilderHelpers(eventBuilder);
-        raven.sendEvent(eventBuilder.build());
+        raven.sendEvent(eventBuilder.build());*/
     }
 }
diff --git a/src/main/java/com/comandante/creeper/merchant/GrimulfWizard.java b/src/main/java/com/comandante/creeper/merchant/GrimulfWizard.java
old mode 100755
new mode 100644
diff --git a/src/main/java/com/comandante/creeper/merchant/KetilCommissary.java b/src/main/java/com/comandante/creeper/merchant/KetilCommissary.java
old mode 100755
new mode 100644
diff --git a/src/main/java/com/comandante/creeper/merchant/Merchant.java b/src/main/java/com/comandante/creeper/merchant/Merchant.java
old mode 100755
new mode 100644
diff --git a/src/main/java/com/comandante/creeper/merchant/Wizard.java b/src/main/java/com/comandante/creeper/merchant/Wizard.java
new file mode 100644
index 0000000000000000000000000000000000000000..00a27a7ecede289954db33299188373c952c15ea
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/merchant/Wizard.java
@@ -0,0 +1,41 @@
+package com.comandante.creeper.merchant;
+
+import com.comandante.creeper.Items.Loot;
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.server.Color;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static com.comandante.creeper.server.Color.BOLD_ON;
+
+public class Wizard extends Merchant {
+    private final static long phraseIntervalMs = 300000;
+    private final static String NAME = "willy the wizard";
+    private final static String welcomeMessage = "  ____                                        \n" +
+            " 6MMMMb\\                                      \n" +
+            "6M'    `   /                                  \n" +
+            "MM        /M       _____     _____   __ ____  \n" +
+            "YM.      /MMMMM   6MMMMMb   6MMMMMb  `M6MMMMb \n" +
+            " YMMMMb   MM     6M'   `Mb 6M'   `Mb  MM'  `Mb\n" +
+            "     `Mb  MM     MM     MM MM     MM  MM    MM\n" +
+            "      MM  MM     MM     MM MM     MM  MM    MM\n" +
+            "      MM  MM     MM     MM MM     MM  MM    MM\n" +
+            "L    ,M9  YM.  , YM.   ,M9 YM.   ,M9  MM.  ,M9\n" +
+            "MYMMMM9    YMMM9  YMMMMM9   YMMMMM9   MMYMMM9 \n" +
+            "                                      MM      \n" +
+            "                                      MM      \n" +
+            "                                     _MM_     \n" +
+            "\n";
+    private final static Set<String> validTriggers = new HashSet<String>(Arrays.asList(new String[]
+            {"wizard", "willy the wizard", "willy", NAME}
+    ));
+
+    private final static String colorName = BOLD_ON + Color.BLUE + NAME  + Color.RESET ;
+
+    public Wizard(GameManager gameManager, Loot loot, Map<Integer, MerchantItemForSale> merchantItemForSales) {
+        super(gameManager, NAME, colorName, validTriggers, merchantItemForSales, welcomeMessage);
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/merchant/bank/commands/BankCommand.java b/src/main/java/com/comandante/creeper/merchant/bank/commands/BankCommand.java
index 9921b8b6549b1b34ee0d6ddd582def53ae94b9b8..2b15253c5d45eaddff9014eaec7a555219182425 100644
--- a/src/main/java/com/comandante/creeper/merchant/bank/commands/BankCommand.java
+++ b/src/main/java/com/comandante/creeper/merchant/bank/commands/BankCommand.java
@@ -4,7 +4,7 @@ import com.comandante.creeper.Main;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerManager;
-import com.comandante.creeper.server.ChannelUtils;
+import com.comandante.creeper.server.ChannelCommunicationUtils;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.server.CreeperSession;
 import com.comandante.creeper.world.Room;
@@ -23,7 +23,7 @@ public class BankCommand extends SimpleChannelUpstreamHandler {
     public final List<String> validTriggers;
     public final GameManager gameManager;
     public final PlayerManager playerManager;
-    public final ChannelUtils channelUtils;
+    public final ChannelCommunicationUtils channelUtils;
     public CreeperSession creeperSession;
     public Player player;
     public String playerId;
diff --git a/src/main/java/com/comandante/creeper/merchant/bank/commands/DepositCommand.java b/src/main/java/com/comandante/creeper/merchant/bank/commands/DepositCommand.java
index 80678b0b9d7a3f0518d4432853dad8719422d502..40190be59ba374b1c6af2f3ed7df57c7299b8a53 100644
--- a/src/main/java/com/comandante/creeper/merchant/bank/commands/DepositCommand.java
+++ b/src/main/java/com/comandante/creeper/merchant/bank/commands/DepositCommand.java
@@ -4,6 +4,7 @@ package com.comandante.creeper.merchant.bank.commands;
 import com.comandante.creeper.command.Command;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.server.Color;
+import org.apache.commons.lang.math.NumberUtils;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -25,7 +26,7 @@ public class DepositCommand extends BankCommand {
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
         configure(e);
         try {
-            if (originalMessageParts.size() > 1 && Command.isLong(originalMessageParts.get(1))) {
+            if (originalMessageParts.size() > 1 && NumberUtils.isNumber(originalMessageParts.get(1))) {
                 long depositAmt = Long.parseLong(originalMessageParts.get(1));
                 if (areFundsAvailable(depositAmt)) {
                     player.transferGoldToBank(depositAmt);
diff --git a/src/main/java/com/comandante/creeper/merchant/bank/commands/DoneCommand.java b/src/main/java/com/comandante/creeper/merchant/bank/commands/DoneCommand.java
index e2201dcd601af69f530d2ad0c05fcfd68e044cf8..e243a3c1018928a34df49bda669cb8783eb9af79 100644
--- a/src/main/java/com/comandante/creeper/merchant/bank/commands/DoneCommand.java
+++ b/src/main/java/com/comandante/creeper/merchant/bank/commands/DoneCommand.java
@@ -4,13 +4,13 @@ package com.comandante.creeper.merchant.bank.commands;
 import com.comandante.creeper.CreeperEntry;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.merchant.Merchant;
-import com.google.common.base.Optional;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 
 public class DoneCommand extends BankCommand {
 
@@ -25,7 +25,7 @@ public class DoneCommand extends BankCommand {
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
         configure(e);
         gameManager.getChannelUtils().write(playerId, "Thanks, COME AGAIN." + "\r\n", true);
-        creeperSession.setGrabMerchant(Optional.<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>>absent());
+        creeperSession.setGrabMerchant(Optional.<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>>empty());
         e.getChannel().getPipeline().remove("executed_command");
         e.getChannel().getPipeline().remove("executed_bank_command");
         String s = gameManager.buildPrompt(playerId);
diff --git a/src/main/java/com/comandante/creeper/merchant/bank/commands/WithdrawalCommand.java b/src/main/java/com/comandante/creeper/merchant/bank/commands/WithdrawalCommand.java
index 378ecbfa9f8f4ee48fda6e3032b6ff4205eb8c99..578ab5ce499b99e13aab29fb9acabac993a7b8f4 100644
--- a/src/main/java/com/comandante/creeper/merchant/bank/commands/WithdrawalCommand.java
+++ b/src/main/java/com/comandante/creeper/merchant/bank/commands/WithdrawalCommand.java
@@ -3,6 +3,7 @@ package com.comandante.creeper.merchant.bank.commands;
 import com.comandante.creeper.command.Command;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.server.Color;
+import org.apache.commons.lang.math.NumberUtils;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -24,7 +25,7 @@ public class WithdrawalCommand extends BankCommand {
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
         configure(e);
         try {
-            if (originalMessageParts.size() > 1 && Command.isInteger(originalMessageParts.get(1))) {
+            if (originalMessageParts.size() > 1 && NumberUtils.isNumber(originalMessageParts.get(1))) {
                 int withdrawalAmount = Integer.parseInt(originalMessageParts.get(1));
                 if (areBankFundsAvailable(withdrawalAmount)) {
                     player.transferBankGoldToPlayer(withdrawalAmount);
diff --git a/src/main/java/com/comandante/creeper/merchant/lockers/DoneCommand.java b/src/main/java/com/comandante/creeper/merchant/lockers/DoneCommand.java
index ec47ee73799d29e72d463fdd897a41a0eadfa5c6..35111419a6e27c6d8ef6990e26a8f61a2c22bd90 100644
--- a/src/main/java/com/comandante/creeper/merchant/lockers/DoneCommand.java
+++ b/src/main/java/com/comandante/creeper/merchant/lockers/DoneCommand.java
@@ -3,13 +3,13 @@ package com.comandante.creeper.merchant.lockers;
 import com.comandante.creeper.CreeperEntry;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.merchant.Merchant;
-import com.google.common.base.Optional;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 
 public class DoneCommand extends LockerCommand {
 
@@ -23,7 +23,7 @@ public class DoneCommand extends LockerCommand {
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
         configure(e);
-        creeperSession.setGrabMerchant(Optional.<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>>absent());
+        creeperSession.setGrabMerchant(Optional.<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>>empty());
         e.getChannel().getPipeline().remove("executed_command");
         e.getChannel().getPipeline().remove("executed_locker_command");
         String s = gameManager.buildPrompt(playerId);
diff --git a/src/main/java/com/comandante/creeper/merchant/lockers/LockerCommand.java b/src/main/java/com/comandante/creeper/merchant/lockers/LockerCommand.java
index 3cf0b00b929468de39591933775b4251a1b4fa94..7088cc9bad164aaa37f1ed6158f394456a74c357 100644
--- a/src/main/java/com/comandante/creeper/merchant/lockers/LockerCommand.java
+++ b/src/main/java/com/comandante/creeper/merchant/lockers/LockerCommand.java
@@ -4,7 +4,7 @@ import com.comandante.creeper.Main;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerManager;
-import com.comandante.creeper.server.ChannelUtils;
+import com.comandante.creeper.server.ChannelCommunicationUtils;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.server.CreeperSession;
 import com.comandante.creeper.world.Room;
@@ -23,7 +23,7 @@ public class LockerCommand extends SimpleChannelUpstreamHandler {
     public final List<String> validTriggers;
     public final GameManager gameManager;
     public final PlayerManager playerManager;
-    public final ChannelUtils channelUtils;
+    public final ChannelCommunicationUtils channelUtils;
     public CreeperSession creeperSession;
     public Player player;
     public String playerId;
diff --git a/src/main/java/com/comandante/creeper/npc/Npc.java b/src/main/java/com/comandante/creeper/npc/Npc.java
index 98ff0ac2bfc36fc656b5ed1cc6778b4a5c394ce1..76a630d4fdfb6a3a68e8146d9b93968521f50adf 100644
--- a/src/main/java/com/comandante/creeper/npc/Npc.java
+++ b/src/main/java/com/comandante/creeper/npc/Npc.java
@@ -7,9 +7,7 @@ import com.comandante.creeper.Items.Rarity;
 import com.comandante.creeper.entity.CreeperEntity;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.managers.SentryManager;
-import com.comandante.creeper.player.CoolDown;
-import com.comandante.creeper.player.CoolDownType;
-import com.comandante.creeper.player.Player;
+import com.comandante.creeper.player.*;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.spawner.SpawnRule;
 import com.comandante.creeper.spells.Effect;
@@ -19,13 +17,13 @@ import com.comandante.creeper.stat.StatsHelper;
 import com.comandante.creeper.world.Area;
 import com.comandante.creeper.world.Room;
 import com.google.api.client.util.Sets;
-import com.google.common.base.Optional;
 import com.google.common.collect.Interner;
 import com.google.common.collect.Interners;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.nocrala.tools.texttablefmt.BorderStyle;
 import org.nocrala.tools.texttablefmt.ShownBorders;
+import org.nocrala.tools.texttablefmt.Table;
 
 import java.text.NumberFormat;
 import java.util.*;
@@ -38,29 +36,31 @@ import static com.comandante.creeper.server.Color.RESET;
 
 public class Npc extends CreeperEntity {
 
-    private long lastPhraseTimestamp;
     private final GameManager gameManager;
     private final String name;
     private final String colorName;
     private final Stats stats;
     private final String dieMessage;
+    private final Temperament temperament;
     private final Set<Area> roamAreas;
     private final Set<String> validTriggers;
-    private Loot loot;
     private final Set<SpawnRule> spawnRules;
+    private final ArrayBlockingQueue<NpcStatsChange> npcStatsChanges = new ArrayBlockingQueue<>(3000);
+    private final Interner<Npc> interner = Interners.newWeakInterner();
+    private final AtomicBoolean isAlive = new AtomicBoolean(true);
+    private final Random random = new Random();
+    private long lastPhraseTimestamp;
+    private Loot loot;
     private List<Effect> effects = Lists.newCopyOnWriteArrayList();
     private int maxEffects = 4;
     private Map<String, Long> playerDamageMap = Maps.newHashMap();
     private Room currentRoom;
-    private final ArrayBlockingQueue<NpcStatsChange> npcStatsChanges = new ArrayBlockingQueue<>(3000);
     private int effectsTickBucket = 0;
-    private final Interner<Npc> interner = Interners.newWeakInterner();
-    private final AtomicBoolean isAlive = new AtomicBoolean(true);
     private Set<CoolDown> coolDowns = Sets.newHashSet();
-    private final Random random = new Random();
+    private final ExperienceManager experienceManager = new ExperienceManager();
 
 
-    protected Npc(GameManager gameManager, String name, String colorName, long lastPhraseTimestamp, Stats stats, String dieMessage, Set<Area> roamAreas, Set<String> validTriggers, Loot loot, Set<SpawnRule> spawnRules) {
+    protected Npc(GameManager gameManager, String name, String colorName, long lastPhraseTimestamp, Stats stats, String dieMessage, Temperament temperament, Set<Area> roamAreas, Set<String> validTriggers, Loot loot, Set<SpawnRule> spawnRules) {
         this.gameManager = gameManager;
         this.name = name;
         this.colorName = colorName;
@@ -71,6 +71,7 @@ public class Npc extends CreeperEntity {
         this.validTriggers = validTriggers;
         this.loot = loot;
         this.spawnRules = spawnRules;
+        this.temperament = temperament;
     }
 
     @Override
@@ -79,6 +80,8 @@ public class Npc extends CreeperEntity {
             try {
                 if (isAlive.get()) {
                     if (effectsTickBucket == 5) {
+
+                        // START Process NPC Effects
                         for (Effect effect : effects) {
                             if (effect.getEffectApplications() >= effect.getMaxEffectApplications()) {
                                 Optional<Room> npcCurrentRoom = gameManager.getRoomManager().getNpcCurrentRoom(this);
@@ -96,10 +99,13 @@ public class Npc extends CreeperEntity {
                                 gameManager.getEntityManager().saveEffect(effect);
                             }
                         }
+                        // END Process Npc Effects
+
                         effectsTickBucket = 0;
                     } else {
                         effectsTickBucket++;
                     }
+
                     List<NpcStatsChange> npcStatsChangeList = Lists.newArrayList();
                     npcStatsChanges.drainTo(npcStatsChangeList);
                     for (NpcStatsChange npcStatsChange : npcStatsChangeList) {
@@ -119,6 +125,66 @@ public class Npc extends CreeperEntity {
         }
     }
 
+    public String getName() {
+        return name;
+    }
+
+    private void processNpcStatChange(NpcStatsChange npcStatsChange) {
+        try {
+            if (npcStatsChange.getPlayer().isActive(CoolDownType.DEATH) && !npcStatsChange.isItemDamage()) {
+                return;
+            }
+            if (!isAlive.get()) {
+                return;
+            }
+            if (npcStatsChange.getStats() == null) {
+                return;
+            }
+            for (String message : npcStatsChange.getDamageStrings()) {
+                if (!npcStatsChange.getPlayer().isActive(CoolDownType.DEATH)) {
+                    gameManager.getChannelUtils().write(npcStatsChange.getPlayer().getPlayerId(), message + "\r\n", true);
+                }
+            }
+            StatsHelper.combineStats(getStats(), npcStatsChange.getStats());
+            long amt = npcStatsChange.getStats().getCurrentHealth();
+            long damageReportAmt = -npcStatsChange.getStats().getCurrentHealth();
+            if (getStats().getCurrentHealth() < 0) {
+                damageReportAmt = -amt + getStats().getCurrentHealth();
+                getStats().setCurrentHealth(0);
+            }
+            long damage = 0;
+            if (getPlayerDamageMap().containsKey(npcStatsChange.getPlayer().getPlayerId())) {
+                damage = getPlayerDamageMap().get(npcStatsChange.getPlayer().getPlayerId());
+            }
+            addDamageToMap(npcStatsChange.getPlayer().getPlayerId(), damage + damageReportAmt);
+            if (getStats().getCurrentHealth() == 0) {
+                killNpc(npcStatsChange.getPlayer());
+                return;
+            }
+            if (npcStatsChange.getPlayerStatsChange() != null) {
+                for (String message : npcStatsChange.getPlayerDamageStrings()) {
+                    if (!npcStatsChange.getPlayer().isActive(CoolDownType.DEATH)) {
+                        gameManager.getChannelUtils().write(npcStatsChange.getPlayer().getPlayerId(), message + "\r\n", true);
+                        npcStatsChange.getPlayer().updatePlayerHealth(npcStatsChange.getPlayerStatsChange().getCurrentHealth(), this);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            SentryManager.logSentry(this.getClass(), e, "Problem processing NPC Stat Change!");
+        }
+    }
+
+    public boolean isActiveCooldown(CoolDownType coolDownType) {
+        for (CoolDown c : coolDowns) {
+            if (c.getCoolDownType().equals(coolDownType)) {
+                if (c.isActive()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     private boolean getRandPercent(double percent) {
         double rangeMin = 0;
         double rangeMax = 100;
@@ -138,23 +204,117 @@ public class Npc extends CreeperEntity {
         }
     }
 
-    public void addCoolDown(CoolDown coolDown) {
-        this.coolDowns.add(coolDown);
+    public Stats getStats() {
+        return stats;
     }
 
-    public Set<CoolDown> getCoolDowns() {
-        return coolDowns;
+    public Map<String, Long> getPlayerDamageMap() {
+        return playerDamageMap;
     }
 
+    public void addDamageToMap(String playerId, long amt) {
+        playerDamageMap.put(playerId, amt);
+    }
 
-    public void setLastPhraseTimestamp(long lastPhraseTimestamp) {
-        this.lastPhraseTimestamp = lastPhraseTimestamp;
+    private void killNpc(Player player) {
+        isAlive.set(false);
+        Map<String, Double> damagePercents;
+        Item corpse = new Item(getName() + " corpse", "a bloody corpse.", Arrays.asList("corpse", "c"), "a corpse lies on the ground.", UUID.randomUUID().toString(), Item.CORPSE_ID_RESERVED, 0, false, 120, Rarity.BASIC, 0, getLoot());
+        if (!player.isActive(CoolDownType.DEATH)) {
+            gameManager.writeToPlayerCurrentRoom(player.getPlayerId(), getDieMessage() + "\r\n");
+        }
+        damagePercents = gameManager.processExperience(this, getCurrentRoom());
+        gameManager.getEntityManager().saveItem(corpse);
+        Integer roomId = gameManager.getRoomManager().getNpcCurrentRoom(this).get().getRoomId();
+        Room room = gameManager.getRoomManager().getRoom(roomId);
+        room.addPresentItem(corpse.getItemId());
+        gameManager.getItemDecayManager().addItem(corpse);
+        getCurrentRoom().removePresentNpc(getEntityId());
+        gameManager.getEntityManager().deleteNpcEntity(getEntityId());
+        player.removeActiveFight(this);
+        for (Map.Entry<String, Double> playerDamagePercent : damagePercents.entrySet()) {
+            Player p = gameManager.getPlayerManager().getPlayer(playerDamagePercent.getKey());
+            if (p == null) {
+                continue;
+            }
+            Double playerDamagePercentValue = playerDamagePercent.getValue();
+
+            int playerLevel = (int) Levels.getLevel(gameManager.getStatsModifierFactory().getStatsModifier(player).getExperience());
+            int npcLevel = (int) Levels.getLevel(this.getStats().getExperience());
+
+            long xpEarned = (long) (experienceManager.calculateNpcXp(playerLevel, npcLevel) * playerDamagePercentValue);
+            p.addExperience(xpEarned);
+            gameManager.getChannelUtils().write(p.getPlayerId(), getBattleReport(xpEarned) + "\r\n", true);
+            p.addNpcKillLog(getName());
+        }
     }
 
+    public Loot getLoot() {
+        return loot;
+    }
+
+    public String getDieMessage() {
+        return dieMessage;
+    }
+
+    public Room getCurrentRoom() {
+        return currentRoom;
+    }
+
+    public void setCurrentRoom(Room currentRoom) {
+        this.currentRoom = currentRoom;
+    }
+
+
+    private String getBattleReport(long xpEarned) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(Color.MAGENTA).append("Battle Report----------------------------").append(Color.RESET).append("\r\n");
+        sb.append("You killed a ");
+        sb.append(getColorName());
+        sb.append(" for ");
+        sb.append(Color.GREEN);
+        sb.append("+");
+        sb.append(NumberFormat.getNumberInstance(Locale.US).format(xpEarned));
+        sb.append(Color.RESET);
+        sb.append(" experience points.");
+        sb.append("\r\n");
+
+        Set<Map.Entry<String, Long>> entries = getPlayerDamageMap().entrySet();
+        Table t = new Table(2, BorderStyle.CLASSIC_COMPATIBLE,
+                ShownBorders.NONE);
+
+        t.setColumnWidth(0, 14, 24);
+        t.setColumnWidth(1, 10, 13);
+        t.addCell("Player");
+        t.addCell("Damage");
+        for (Map.Entry<String, Long> entry : entries) {
+            Player player = gameManager.getPlayerManager().getPlayer(entry.getKey());
+            String name = null;
+            if (player != null) {
+                name = player.getPlayerName();
+            }
+            long damageAmt = entry.getValue();
+            t.addCell(name);
+            t.addCell(NumberFormat.getNumberInstance(Locale.US).format(damageAmt));
+        }
+        sb.append(t.render());
+        return sb.toString();
+    }
+
+
+
     public String getColorName() {
         return colorName;
     }
 
+    public void setLoot(Loot loot) {
+        this.loot = loot;
+    }
+
+    public Set<CoolDown> getCoolDowns() {
+        return coolDowns;
+    }
+
     public Set<String> getValidTriggers() {
         return validTriggers;
     }
@@ -163,10 +323,6 @@ public class Npc extends CreeperEntity {
         return roamAreas;
     }
 
-    public Stats getStats() {
-        return stats;
-    }
-
     public GameManager getGameManager() {
         return gameManager;
     }
@@ -175,12 +331,8 @@ public class Npc extends CreeperEntity {
         return lastPhraseTimestamp;
     }
 
-    public String getName() {
-        return name;
-    }
-
-    public String getDieMessage() {
-        return dieMessage;
+    public void setLastPhraseTimestamp(long lastPhraseTimestamp) {
+        this.lastPhraseTimestamp = lastPhraseTimestamp;
     }
 
     public void npcSay(Integer roomId, String message) {
@@ -190,22 +342,18 @@ public class Npc extends CreeperEntity {
         sb.append(RESET);
     }
 
-    public Loot getLoot() {
-        return loot;
-    }
-
-    public Set<SpawnRule> getSpawnRules() {
-        return spawnRules;
-    }
-
     public Optional<SpawnRule> getSpawnRuleByArea(Area area) {
         Set<SpawnRule> spawnRules = getSpawnRules();
-        for (SpawnRule spawnRule: spawnRules) {
+        for (SpawnRule spawnRule : spawnRules) {
             if (spawnRule.getArea().equals(area)) {
                 return Optional.of(spawnRule);
             }
         }
-        return Optional.absent();
+        return Optional.empty();
+    }
+
+    public Set<SpawnRule> getSpawnRules() {
+        return spawnRules;
     }
 
     public void addEffect(Effect effect) {
@@ -226,35 +374,25 @@ public class Npc extends CreeperEntity {
         return getStats().getExperience();
     }
 
-    public double getPctOFExperience(double pct, long playerLevel) {
-        return getExperience() * pct;
-    }
-
-    public void addDamageToMap(String playerId, long amt) {
-        playerDamageMap.put(playerId, amt);
-    }
-
-    public Map<String, Long> getPlayerDamageMap() {
-        return playerDamageMap;
-    }
-
-    public void setLoot(Loot loot) {
-        this.loot = loot;
+    public Temperament getTemperament() {
+        return temperament;
     }
 
-    public Room getCurrentRoom() {
-        return currentRoom;
+    public AtomicBoolean getIsAlive() {
+        return isAlive;
     }
 
-    public void setCurrentRoom(Room currentRoom) {
-        this.currentRoom = currentRoom;
+    public void doHealthDamage(Player player, List<String> damageStrings, long amt) {
+        NpcStatsChange npcStatsChange =
+                new NpcStatsChangeBuilder().setStats(new StatsBuilder().setCurrentHealth(amt).createStats()).setDamageStrings(damageStrings).setPlayer(player).createNpcStatsChange();
+        addNpcDamage(npcStatsChange);
     }
 
     public void addNpcDamage(NpcStatsChange npcStatsChange) {
         if (!isActiveCooldown(CoolDownType.NPC_FIGHT)) {
             addCoolDown(new CoolDown(CoolDownType.NPC_FIGHT));
         } else {
-            for (CoolDown coolDown: coolDowns) {
+            for (CoolDown coolDown : coolDowns) {
                 if (coolDown.getCoolDownType().equals(CoolDownType.NPC_FIGHT)) {
                     coolDown.setNumberOfTicks(coolDown.getOriginalNumberOfTicks());
                 }
@@ -263,128 +401,31 @@ public class Npc extends CreeperEntity {
         this.npcStatsChanges.add(npcStatsChange);
     }
 
-    public boolean isActiveCooldown(CoolDownType coolDownType) {
-        for (CoolDown c : coolDowns) {
-            if (c.getCoolDownType().equals(coolDownType)) {
-                if (c.isActive()) {
-                    return true;
-                }
-            }
-        }
-        return false;
+    public void addCoolDown(CoolDown coolDown) {
+        this.coolDowns.add(coolDown);
     }
 
-
-    public void doHealthDamage(Player player, List<String> damageStrings, long amt) {
-        NpcStatsChange npcStatsChange =
-                new NpcStatsChangeBuilder().setStats(new StatsBuilder().setCurrentHealth(amt).createStats()).setDamageStrings(damageStrings).setPlayer(player).createNpcStatsChange();
-        addNpcDamage(npcStatsChange);
+    public NpcLevelColor getLevelColor(int playerLevel) {
+        return experienceManager.getLevelColor(playerLevel, (int) Levels.getLevel(this.getStats().getExperience()));
     }
 
-    private void processNpcStatChange(NpcStatsChange npcStatsChange) {
-        try {
-            if (npcStatsChange.getPlayer().isActive(CoolDownType.DEATH) && !npcStatsChange.isItemDamage()) {
-                return;
-            }
-            if (isAlive.get()) {
-                if (npcStatsChange.getStats() != null) {
-                    for (String message : npcStatsChange.getDamageStrings()) {
-                        if (!npcStatsChange.getPlayer().isActive(CoolDownType.DEATH)) {
-                            gameManager.getChannelUtils().write(npcStatsChange.getPlayer().getPlayerId(), message + "\r\n", true);
-                        }
-                    }
-                    StatsHelper.combineStats(getStats(), npcStatsChange.getStats());
-                    long amt = npcStatsChange.getStats().getCurrentHealth();
-                    long damageReportAmt = -npcStatsChange.getStats().getCurrentHealth();
-                    if (getStats().getCurrentHealth() < 0) {
-                        damageReportAmt = -amt + getStats().getCurrentHealth();
-                        getStats().setCurrentHealth(0);
-                    }
-                    long damage = 0;
-                    if (getPlayerDamageMap().containsKey(npcStatsChange.getPlayer().getPlayerId())) {
-                        damage = getPlayerDamageMap().get(npcStatsChange.getPlayer().getPlayerId());
-                    }
-                    addDamageToMap(npcStatsChange.getPlayer().getPlayerId(), damage + damageReportAmt);
-                    if (getStats().getCurrentHealth() == 0) {
-                        killNpc(npcStatsChange.getPlayer());
-                        return;
-                    }
-                }
-                if (npcStatsChange.getPlayerStatsChange() != null) {
-                    for (String message : npcStatsChange.getPlayerDamageStrings()) {
-                        if (!npcStatsChange.getPlayer().isActive(CoolDownType.DEATH)) {
-                            gameManager.getChannelUtils().write(npcStatsChange.getPlayer().getPlayerId(), message + "\r\n", true);
-                            npcStatsChange.getPlayer().updatePlayerHealth(npcStatsChange.getPlayerStatsChange().getCurrentHealth(), this);
-                        }
-                    }
-                }
-            }
-        } catch (Exception e) {
-            SentryManager.logSentry(this.getClass(), e, "Problem processing NPC Stat Change!");
+    public enum NpcLevelColor {
 
-        }
-    }
+    RED(Color.RED + "Red"),
+    ORANGE(Color.CYAN + "Cyan"),
+    YELLOW(Color.YELLOW + "Yellow"),
+    GREEN(Color.GREEN + "Green"),
+    WHITE(Color.WHITE + "White");
 
-    private String getBattleReport(long xpEarned) {
-        StringBuilder sb = new StringBuilder();
-        sb.append(Color.MAGENTA).append("Battle Report----------------------------").append(Color.RESET).append("\r\n");
-        sb.append("You killed a ");
-        sb.append(getColorName());
-        sb.append(" for ");
-        sb.append(Color.GREEN);
-        sb.append("+");
-        sb.append(NumberFormat.getNumberInstance(Locale.US).format(xpEarned));
-        sb.append(Color.RESET);
-        sb.append(" experience points.");
-        sb.append("\r\n");
-
-        Set<Map.Entry<String, Long>> entries = getPlayerDamageMap().entrySet();
-        org.nocrala.tools.texttablefmt.Table t = new org.nocrala.tools.texttablefmt.Table(2, BorderStyle.CLASSIC_COMPATIBLE,
-                ShownBorders.NONE);
+    private final String color;
 
-        t.setColumnWidth(0, 14, 24);
-        t.setColumnWidth(1, 10, 13);
-        t.addCell("Player");
-        t.addCell("Damage");
-        for (Map.Entry<String, Long> entry : entries) {
-            Player player = gameManager.getPlayerManager().getPlayer(entry.getKey());
-            String name = null;
-            if (player != null) {
-                name = player.getPlayerName();
-            }
-            long damageAmt = entry.getValue();
-            t.addCell(name);
-            t.addCell(NumberFormat.getNumberInstance(Locale.US).format(damageAmt));
-        }
-        sb.append(t.render());
-        return sb.toString();
+    NpcLevelColor(String color) {
+        this.color = color;
     }
 
-    private void killNpc(Player player) {
-        isAlive.set(false);
-        Map<String, Double> xpProcessed;
-        Item corpse = new Item(getName() + " corpse", "a bloody corpse.", Arrays.asList("corpse", "c"), "a corpse lies on the ground.", UUID.randomUUID().toString(), Item.CORPSE_ID_RESERVED, 0, false, 120, Rarity.BASIC, 0, getLoot());
-        if (!player.isActive(CoolDownType.DEATH)) {
-            gameManager.writeToPlayerCurrentRoom(player.getPlayerId(), getDieMessage());
-        }
-        xpProcessed = gameManager.processExperience(this, getCurrentRoom());
-        gameManager.getEntityManager().saveItem(corpse);
-        Integer roomId = gameManager.getRoomManager().getNpcCurrentRoom(this).get().getRoomId();
-        Room room = gameManager.getRoomManager().getRoom(roomId);
-        room.addPresentItem(corpse.getItemId());
-        gameManager.getItemDecayManager().addItem(corpse);
-        getCurrentRoom().removePresentNpc(getEntityId());
-        gameManager.getEntityManager().deleteNpcEntity(getEntityId());
-        player.removeActiveFight(this);
-        for (Map.Entry<String, Double> playerDamageExperience : xpProcessed.entrySet()) {
-            Player p = gameManager.getPlayerManager().getPlayer(playerDamageExperience.getKey());
-            if (p == null) {
-                continue;
-            }
-            long xpEarned = (long) Math.round(playerDamageExperience.getValue());
-            p.addExperience(xpEarned);
-            gameManager.getChannelUtils().write(p.getPlayerId(), getBattleReport(xpEarned) + "\r\n", true);
-        }
+    public String getColor() {
+        return "(" + Color.BOLD_ON + color + Color.RESET + ")";
     }
+}
 
 }
diff --git a/src/main/java/com/comandante/creeper/npc/NpcAdapter.java b/src/main/java/com/comandante/creeper/npc/NpcAdapter.java
index ce58b46dca7b91c46cc3ef704cd4af1a1e14d956..2818044b818083c99b683f6dd7ca22d46e98487a 100644
--- a/src/main/java/com/comandante/creeper/npc/NpcAdapter.java
+++ b/src/main/java/com/comandante/creeper/npc/NpcAdapter.java
@@ -30,7 +30,7 @@ public class NpcAdapter extends TypeAdapter<Npc> {
         jsonWriter.name("name").value(npc.getName());
         jsonWriter.name("colorName").value(npc.getColorName());
         jsonWriter.name("dieMessage").value(npc.getDieMessage());
-
+        jsonWriter.name("temperament").value(npc.getDieMessage());
         Loot loot = npc.getLoot();
         jsonWriter.name("loot");
         jsonWriter.beginObject();
@@ -106,6 +106,8 @@ public class NpcAdapter extends TypeAdapter<Npc> {
         jsonReader.nextName();
         final String npcDieMessage = jsonReader.nextString();
         jsonReader.nextName();
+        final String temperament = jsonReader.nextString();
+        jsonReader.nextName();
         jsonReader.beginObject();
         jsonReader.nextName();
         final long lootGoldMin = jsonReader.nextLong();
@@ -205,6 +207,7 @@ public class NpcAdapter extends TypeAdapter<Npc> {
         NpcBuilder npcBuilder = new NpcBuilder()
                 .setColorName(npcColorName)
                 .setDieMessage(npcDieMessage)
+                .setTemperament(Temperament.get(temperament))
                 .setLoot(loot)
                 .setName(npcName)
                 .setRoamAreas(roamAreas)
diff --git a/src/main/java/com/comandante/creeper/npc/NpcAdapterTest.java b/src/main/java/com/comandante/creeper/npc/NpcAdapterTest.java
index cedd65f7873bc1ba36ad6d473aa22820004b2a98..e5665609bc3d1c4264dddb85c2d2510d0a3e408b 100644
--- a/src/main/java/com/comandante/creeper/npc/NpcAdapterTest.java
+++ b/src/main/java/com/comandante/creeper/npc/NpcAdapterTest.java
@@ -9,14 +9,11 @@ import com.comandante.creeper.stat.Stats;
 import com.comandante.creeper.stat.StatsBuilder;
 import com.comandante.creeper.world.Area;
 import com.google.common.collect.Sets;
-import com.google.common.io.Files;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.io.File;
-import java.nio.charset.Charset;
 import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
@@ -56,7 +53,7 @@ public class NpcAdapterTest {
                 .setWillpower(randomGenerator.nextInt(100))
                 .createStats();
 
-        Loot npcOneLoot = new Loot(randomGenerator.nextInt(100), randomGenerator.nextInt(100), Sets.newHashSet(ItemType.BEER));
+        Loot npcOneLoot = new Loot(randomGenerator.nextInt(100), randomGenerator.nextInt(100), Sets.newHashSet(ItemType.SMALL_HEALTH_POTION));
         SpawnRule npcOneSpawnRule1 = new SpawnRuleBuilder().setArea(Area.BLOODRIDGE10_ZONE).setSpawnIntervalTicks(randomGenerator.nextInt(100)).setMaxInstances(randomGenerator.nextInt(100)).setMaxPerRoom(randomGenerator.nextInt(100)).setRandomPercent(randomGenerator.nextInt(100)).createSpawnRule();
         SpawnRule npcOneSpawnRule2 = new SpawnRuleBuilder().setArea(Area.BLOODRIDGE10_ZONE).setSpawnIntervalTicks(randomGenerator.nextInt(100)).setMaxInstances(randomGenerator.nextInt(100)).setMaxPerRoom(randomGenerator.nextInt(100)).setRandomPercent(randomGenerator.nextInt(100)).createSpawnRule();
         npcOne = new NpcBuilder()
@@ -116,14 +113,4 @@ public class NpcAdapterTest {
         assertEquals(npcOne.getValidTriggers(), npc.getValidTriggers());
 
     }
-
-    @Test
-    public void testRawJson() throws Exception {
-        String testJson = Files.toString(new File("/Users/kearney/Desktop/npcs/tunnelcobra.json"), Charset.defaultCharset());
-        System.out.println(testJson);
-
-        Npc npc = gson.fromJson(testJson, Npc.class);
-
-
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/npc/NpcBuilder.java b/src/main/java/com/comandante/creeper/npc/NpcBuilder.java
index 642bc5482ba9dfcd4453f62eef8811a83789470b..cb111624662377679dd53cdbe5223a5cc1c0f0db 100644
--- a/src/main/java/com/comandante/creeper/npc/NpcBuilder.java
+++ b/src/main/java/com/comandante/creeper/npc/NpcBuilder.java
@@ -19,6 +19,7 @@ public class NpcBuilder {
     private Set<String> validTriggers;
     private Loot loot;
     private Set<SpawnRule> spawnRules;
+    private Temperament temperament;
 
     public NpcBuilder() {
     }
@@ -34,6 +35,7 @@ public class NpcBuilder {
         this.loot = npc.getLoot();
         this.spawnRules = npc.getSpawnRules();
         this.gameManager = npc.getGameManager();
+        this.temperament = npc.getTemperament();
     }
 
     public NpcBuilder setGameManager(GameManager gameManager) {
@@ -66,6 +68,11 @@ public class NpcBuilder {
         return this;
     }
 
+    public NpcBuilder setTemperament(Temperament temperament) {
+        this.temperament = temperament;
+        return this;
+    }
+
     public NpcBuilder setRoamAreas(Set<Area> roamAreas) {
         this.roamAreas = roamAreas;
         return this;
@@ -87,6 +94,6 @@ public class NpcBuilder {
     }
 
     public Npc createNpc() {
-        return new Npc(gameManager, name, colorName, lastPhraseTimestamp, stats, dieMessage, roamAreas, validTriggers, loot, spawnRules);
+        return new Npc(gameManager, name, colorName, lastPhraseTimestamp, stats, dieMessage, temperament, roamAreas, validTriggers, loot, spawnRules);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/npc/NpcMover.java b/src/main/java/com/comandante/creeper/npc/NpcMover.java
index 8619ecbd68a0894f8cd7fef73e1bfe2c42ad8ee6..b3271a732cd8998ebace0d0e6937a01410c80754 100644
--- a/src/main/java/com/comandante/creeper/npc/NpcMover.java
+++ b/src/main/java/com/comandante/creeper/npc/NpcMover.java
@@ -6,7 +6,6 @@ import com.comandante.creeper.player.CoolDownType;
 import com.comandante.creeper.spawner.SpawnRule;
 import com.comandante.creeper.world.Area;
 import com.comandante.creeper.world.Room;
-import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
@@ -14,6 +13,7 @@ import com.google.common.collect.Sets;
 import org.apache.log4j.Logger;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.Random;
 import java.util.Set;
 
diff --git a/src/main/java/com/comandante/creeper/npc/Temperament.java b/src/main/java/com/comandante/creeper/npc/Temperament.java
new file mode 100644
index 0000000000000000000000000000000000000000..69ee1d12edd0b241d6715f1108236c6ad5e49cf6
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/npc/Temperament.java
@@ -0,0 +1,25 @@
+package com.comandante.creeper.npc;
+
+public enum Temperament {
+    AGGRESSIVE("Aggressive"),
+    PASSIVE("Passive");
+
+    private final String friendlyFormat;
+
+    Temperament(String friendlyFormat) {
+        this.friendlyFormat = friendlyFormat;
+    }
+
+    public String getFriendlyFormat() {
+        return friendlyFormat;
+    }
+
+    public static Temperament get(String s) {
+        for (Temperament t : Temperament.values()) {
+            if (t.name().equalsIgnoreCase(s)) {
+                return t;
+            }
+        }
+        return null;
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/player/CoolDownType.java b/src/main/java/com/comandante/creeper/player/CoolDownType.java
index 1e1d98d34e673b7a25a00896434258c7f373595b..2993ef20b5e7a2988fd2593b1d917efc2578a097 100644
--- a/src/main/java/com/comandante/creeper/player/CoolDownType.java
+++ b/src/main/java/com/comandante/creeper/player/CoolDownType.java
@@ -10,7 +10,8 @@ public enum CoolDownType {
     FORAGE_SUPERSHORT("forage-supershort", 1),
     SPELL("",0),
     NPC_FIGHT("fight",30),
-    NPC_ROAM("npc-roam", 600);
+    NPC_ROAM("npc-roam", 1200),
+    NPC_ALERTED("npc-alerted", 30);
     private final String name;
     private final int ticks;
 
diff --git a/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java b/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java
old mode 100755
new mode 100644
index aa6d3c44143012881c3d10c58988ec285a0a93c4..5ec8b97347f793c0cb51664bb9bb86f24ee59d09
--- a/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java
+++ b/src/main/java/com/comandante/creeper/player/EquipmentBuilder.java
@@ -3,364 +3,80 @@ package com.comandante.creeper.player;
 
 import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.Items.ItemType;
-import com.comandante.creeper.server.Color;
-import com.comandante.creeper.spells.Effect;
-import com.comandante.creeper.spells.EffectBuilder;
 import com.comandante.creeper.stat.Stats;
 import com.comandante.creeper.stat.StatsBuilder;
-import com.google.api.client.util.Lists;
-import com.google.api.client.util.Sets;
-
-import java.util.List;
-import java.util.Set;
 
 public class EquipmentBuilder {
 
-    public static Item Build(Item item) {
+    public static Item build(Item item) {
         ItemType itemType = ItemType.itemTypeFromCode(item.getItemTypeId());
         if (itemType != null) {
             switch (itemType) {
-                case BROAD_SWORD:
-                    return getBroadSword(item);
-                case IRON_BOOTS:
-                    return getIronBoots(item);
-                case IRON_CHEST_PLATE:
-                    return getIronChestPlate(item);
-                case IRON_LEGGINGS:
-                    return getIronLeggings(item);
-                case PHANTOM_SWORD:
-                    return getPhantomSword(item);
-                case IRON_BRACERS:
-                    return getIronBracers(item);
-                case IRON_HELMET:
-                    return getIronHelmet(item);
-                case PHANTOM_HELMET:
-                    return getPhantomHelmet(item);
-                case PHANTOM_CHESTPLATE:
-                    return getPhantomChestplate(item);
-                case PHANTOM_BOOTS:
-                    return getPhantomBoots(item);
-                case PHANTOM_LEGGINGS:
-                    return getPhantomLeggings(item);
-                case PHANTOM_BRACERS:
-                    return getPhantomBracers(item);
-                case MITHRIL_SWORD:
-                    return getMithrilSword(item);
-                case MITHRIL_CHESTPLATE:
-                    return getMithrilChestplate(item);
-                case MITHRIL_HELMET:
-                    return getMithrilHelmet(item);
-                case MITHRIL_BRACERS:
-                    return getMithrilBracers(item);
-                case MITHRIL_LEGGINGS:
-                    return getMithrilLeggings(item);
-                case MITHRIL_BOOTS:
-                    return getMithrilBoots(item);
-                case PYAMITE_SWORD:
-                    return getPyamiteSword(item);
-                case PYAMITE_CHESTPLATE:
-                    return getPyamiteChestplate(item);
-                case PYAMITE_HELMET:
-                    return getPyamiteHelmet(item);
-                case PYAMITE_BRACERS:
-                    return getPyamiteBracers(item);
-                case PYAMITE_LEGGINGS:
-                    return getPyamiteLeggings(item);
-                case PYAMITE_BOOTS:
-                    return getPyamiteBoots(item);
-                case TAPPERHET_SWORD:
-                    return getTapperhetSword(item);
-                case VULCERIUM_SWORD:
-                    return getVulceriumSword(item);
-                case VULCERIUM_CHESTPLATE:
-                    return getVulceriumChestplate(item);
-                case VULCERIUM_HELMET:
-                    return getVulceriumHelmet(item);
-                case VULCERIUM_BRACERS:
-                    return getVulceriumBracers(item);
-                case VULCERIUM_LEGGINGS:
-                    return getVulceriumLeggings(item);
-                case VULCERIUM_BOOTS:
-                    return getVulceriumBoots(item);
-                case DWARF_BOOTS_OF_AGILITY:
-                    return getDwarfBootsOfAgility(item);
+                case BERSERKER_BATON:
+                    return getBerserkerBaton(item);
+                case BERSEKER_BOOTS:
+                    return getBerserkerBoots(item);
+                case BERSERKER_CHEST:
+                    return getBerserkerChest(item);
+                case BERSEKER_SHORTS:
+                    return getBerserkerShorts(item);
+                case BERSERKER_BRACERS:
+                    return getBerserkerBracers(item);
+                case BERSEKER_HELM:
+                    return getBerserkerHelm(item);
                 case LEATHER_SATCHEL:
                     return getLeatherSatchel(item);
                 case BIGGERS_SKIN_SATCHEL:
                     return getBiggersSkinSatchel(item);
-                case STRENGTH_ELIXIR:
-                    return getStrengthElixir(item);
-                case CHRONIC_JOOSE:
-                    return getChronicJoose(item);
-                case BISMUTH_BOOTS:
-                    return getBismuthBoots(item);
-                case BISMUTH_BRACERS:
-                    return getBismuthBracers(item);
-                case BISMUTH_CHESTPLATE:
-                    return getBismuthChestplate(item);
-                case BISMUTH_HELMET:
-                    return getBismuthHelmet(item);
-                case BISMUTH_LEGGINGS:
-                    return getBismuthLeggings(item);
-                case BISMUTH_SWORD:
-                    return getBismuthSword(item);
-                case GUCCI_PANTS:
-                    return getGucciPants(item);
-                case AEXIUM_BOOTS:
-                    return getAexiumBoots(item);
-                case AEXIUM_BRACERS:
-                    return getAexiumBracers(item);
-                case AEXIUM_CHESTPLATE:
-                    return getAexiumChestplate(item);
-                case AEXIUM_HELMET:
-                    return getAexiumHelmet(item);
-                case AEXIUM_LEGGINGS:
-                    return getAexiumLeggings(item);
-                case AEXIUM_SWORD:
-                    return getAexiumSword(item);
-                case VIAGRA_SWORD:
-                    return getViagraSword(item);
-                case RADSUIT_CHESTPLATE:
-                    return getRadsuitChestplate(item);
-                case RADSUIT_HELMET:
-                    return getRadsuitHelmet(item);
-                case RADSUIT_BRACERS:
-                    return getRadsuitBracers(item);
-                case RADSUIT_LEGGINGS:
-                    return getRadsuitLeggings(item);
-                case RADSUIT_BOOTS:
-                    return getRadsuitBoots(item);
             }
         }
         return null;
     }
 
-    public static Item getBroadSword(Item item) {
-        Stats stats = new StatsBuilder().setStrength(10).createStats();
+    public static Item getBerserkerBaton(Item item) {
+        Stats stats = new StatsBuilder().setWeaponRatingMin(2).setWeaponRatingMax(3).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
         item.setEquipment(equipment);
         return item;
     }
 
-    public static Item getIronBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(3).createStats();
+    public static Item getBerserkerBoots(Item item) {
+        Stats stats = new StatsBuilder().setArmorRating(1).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
         item.setEquipment(equipment);
         return item;
     }
 
-    public static Item getIronChestPlate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(7).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getIronLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(5).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getIronBracers(Item item) {
+    public static Item getBerserkerChest(Item item) {
         Stats stats = new StatsBuilder().setArmorRating(2).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getIronHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(4).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPhantomSword(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(5).setStrength(15).setWeaponRatingMax(5).setWeaponRatingMin(5).setNumberOfWeaponRolls(1).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPhantomHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(5).setStrength(5).setAgile(5).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPhantomChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(10).setStrength(5).setAgile(4).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPhantomBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(6).setStrength(3).setAgile(1).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPhantomBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(3).setStrength(2).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPhantomLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(6).setStrength(4).setAgile(3).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getMithrilSword(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(10).setStrength(30).setWeaponRatingMax(10).setWeaponRatingMin(10).setNumberOfWeaponRolls(2).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getMithrilChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(18).setStrength(10).setAgile(7).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
         item.setEquipment(equipment);
         return item;
     }
 
-    public static Item getMithrilHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(9).setStrength(9).setAgile(7).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getMithrilBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(6).setStrength(5).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getMithrilLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(12).setStrength(8).setAgile(6).createStats();
+    public static Item getBerserkerShorts(Item item) {
+        Stats stats = new StatsBuilder().setArmorRating(3).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
         item.setEquipment(equipment);
         return item;
     }
 
-    public static Item getMithrilBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(12).setStrength(6).setAgile(2).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPyamiteSword(Item item){
-        Stats stats = new StatsBuilder().setArmorRating(19).setStrength(44).setWeaponRatingMax(28).setWeaponRatingMin(17).setNumberOfWeaponRolls(2).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPyamiteChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(36).setStrength(20).setAgile(14).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPyamiteHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(18).setStrength(18).setAgile(14).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPyamiteBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(12).setStrength(10).createStats();
+    public static Item getBerserkerBracers(Item item) {
+        Stats stats = new StatsBuilder().setArmorRating(1).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
         item.setEquipment(equipment);
         return item;
     }
 
-    public static Item getPyamiteLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(24).setStrength(16).setAgile(12).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getPyamiteBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(24).setStrength(12).setAgile(24).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getTapperhetSword(Item item){
-        Stats stats = new StatsBuilder().setAgile(40).setArmorRating(27).setStrength(64).setWeaponRatingMax(37).setWeaponRatingMin(28).setNumberOfWeaponRolls(2).setForaging(20000).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getVulceriumSword(Item item){
-        Stats stats = new StatsBuilder().setArmorRating(60).setStrength(120).setWeaponRatingMax(60).setWeaponRatingMin(50).setNumberOfWeaponRolls(3).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getVulceriumChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(100).setStrength(60).setAgile(45).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getVulceriumHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(55).setStrength(55).setAgile(39).createStats();
+    public static Item getBerserkerHelm(Item item) {
+        Stats stats = new StatsBuilder().setArmorRating(1).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
         item.setEquipment(equipment);
         return item;
     }
 
-    public static Item getVulceriumBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(38).setStrength(30).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getVulceriumLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(72).setStrength(48).setAgile(36).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getVulceriumBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(74).setStrength(37).setAgile(60).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getDwarfBootsOfAgility(Item item) {
-        Stats stats = new StatsBuilder().setAgile(400).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
     public static Item getLeatherSatchel(Item item) {
-        Stats stats = new StatsBuilder().setInventorySize(10).createStats();
+        Stats stats = new StatsBuilder().setInventorySize(15).createStats();
         final Equipment equipment = new Equipment(EquipmentSlotType.BAG, stats);
         item.setEquipment(equipment);
         return item;
@@ -372,180 +88,4 @@ public class EquipmentBuilder {
         item.setEquipment(equipment);
         return item;
     }
-
-    public static Item getStrengthElixir(Item item) {
-        EffectBuilder effectBuilder = new EffectBuilder();
-
-        Stats durationStats = new StatsBuilder().setStrength(300).createStats();
-        List<String> applyMessage = Lists.newArrayList();
-        applyMessage.add("A sudden increase of strength is felt pulsing through your veins.");
-
-        Effect effect = effectBuilder.setApplyStatsOnTick(null)
-                .setDurationStats(durationStats)
-                .setEffectApplyMessages(applyMessage)
-                .setEffectDescription("Increase strength for a short period of time.")
-                .setEffectName(Color.RED + "strength" + Color.RESET + " elixir")
-                .setFrozenMovement(false)
-                .setLifeSpanTicks(36).createEffect();
-
-        Set<Effect> effectSet = Sets.newHashSet();
-        effectSet.add(effect);
-        item.setEffects(effectSet);
-        return item;
-    }
-
-    public static Item getChronicJoose(Item item) {
-        EffectBuilder effectBuilder = new EffectBuilder();
-
-        Stats durationStats = new StatsBuilder().setMaxHealth(2000).setMaxMana(1500).createStats();
-        List<String> applyMessage = Lists.newArrayList();
-        applyMessage.add("That " + Color.GREEN + " chronic " + Color.RESET + "joose is pumping through your veins.");
-
-        Effect effect = effectBuilder.setApplyStatsOnTick(null)
-                .setDurationStats(durationStats)
-                .setEffectApplyMessages(applyMessage)
-                .setEffectDescription("Increases mana and health for 10 minutes")
-                .setEffectName(Color.GREEN + "chronic" + Color.RESET + " joose elixir")
-                .setFrozenMovement(false)
-                .setLifeSpanTicks(120).createEffect();
-
-        Set<Effect> effectSet = Sets.newHashSet();
-        effectSet.add(effect);
-        item.setEffects(effectSet);
-        return item;
-    }
-
-    public static Item getBismuthSword(Item item){
-        Stats stats = new StatsBuilder().setArmorRating(2400).setStrength(480).setWeaponRatingMax(2400).setWeaponRatingMin(200).setNumberOfWeaponRolls(6).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getBismuthChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(400).setStrength(2400).setAgile(120).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getBismuthHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(220).setStrength(220).setAgile(87).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getBismuthBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(90).setStrength(120).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getBismuthLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(340).setStrength(160).setAgile(240).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getBismuthBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(220).setStrength(120).setAgile(160).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getGucciPants(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(1000).setStrength(700).setAgile(900).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getAexiumSword(Item item){
-        Stats stats = new StatsBuilder().setArmorRating(6472).setStrength(1261).setWeaponRatingMax(9000).setWeaponRatingMin(1000).setNumberOfWeaponRolls(12).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getAexiumChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(1200).setStrength(6000).setAgile(1135).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getAexiumHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(678).setStrength(531).setAgile(340).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getAexiumBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(300).setStrength(399).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getAexiumLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(1000).setStrength(500).setAgile(900).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getAexiumBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(600).setStrength(340).setAgile(480).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getViagraSword(Item item){
-        Stats stats = new StatsBuilder().setArmorRating(12944).setStrength(6305).setWeaponRatingMax(27000).setWeaponRatingMin(20000).setNumberOfWeaponRolls(24).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HAND, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getRadsuitChestplate(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(1900).setStrength(7000).setAgile(2135).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.CHEST, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getRadsuitHelmet(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(978).setStrength(731).setAgile(640).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.HEAD, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getRadsuitBracers(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(600).setStrength(499).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.WRISTS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getRadsuitLeggings(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(1500).setStrength(800).setAgile(1400).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.LEGS, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
-    public static Item getRadsuitBoots(Item item) {
-        Stats stats = new StatsBuilder().setArmorRating(800).setStrength(540).setAgile(780).createStats();
-        final Equipment equipment = new Equipment(EquipmentSlotType.FEET, stats);
-        item.setEquipment(equipment);
-        return item;
-    }
-
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/player/EquipmentSlotType.java b/src/main/java/com/comandante/creeper/player/EquipmentSlotType.java
index dd990f0719a427112493dee73114fa0914943569..c7617197d79dcaed6ec6fa1b8a234f698b82a87b 100644
--- a/src/main/java/com/comandante/creeper/player/EquipmentSlotType.java
+++ b/src/main/java/com/comandante/creeper/player/EquipmentSlotType.java
@@ -36,14 +36,6 @@ public enum EquipmentSlotType {
     }
 
     public static List<EquipmentSlotType> getAll() {
-        List<EquipmentSlotType> theName = Lists.newArrayList();
-        theName.add(EquipmentSlotType.HEAD);
-        theName.add(EquipmentSlotType.CHEST);
-        theName.add(EquipmentSlotType.WRISTS);
-        theName.add(EquipmentSlotType.HAND);
-        theName.add(EquipmentSlotType.LEGS);
-        theName.add(EquipmentSlotType.FEET);
-        theName.add(EquipmentSlotType.BAG);
-        return theName;
+        return Lists.newArrayList(EquipmentSlotType.values());
     }
 }
diff --git a/src/main/java/com/comandante/creeper/player/ExperienceManager.java b/src/main/java/com/comandante/creeper/player/ExperienceManager.java
index 632f5c9d19cc1901e13bc7fa8c80faca536fad56..8e862f5cceba566adf2b7ddffa0d005d6876aecd 100644
--- a/src/main/java/com/comandante/creeper/player/ExperienceManager.java
+++ b/src/main/java/com/comandante/creeper/player/ExperienceManager.java
@@ -1,5 +1,114 @@
 package com.comandante.creeper.player;
 
+import com.comandante.creeper.npc.Npc;
+
 public class ExperienceManager {
 
+    public static int calculateNpcXp(int playerLevel, int npcLevel) {
+        float xp = 0;
+        if (npcLevel == playerLevel) {
+            xp = (playerLevel * 5 + 45);
+        }
+        if (npcLevel > playerLevel) {
+            float i = playerLevel * 5 + 45;
+            float diff = npcLevel - playerLevel;
+            float modifier = 1 + .2f * (diff);
+            xp = i * modifier;
+        }
+        if (npcLevel < playerLevel) {
+            if (getLevelColor(playerLevel, npcLevel).equals(Npc.NpcLevelColor.WHITE)) {
+                xp = 0;
+            } else {
+                float levelDif = playerLevel - npcLevel;
+                xp = (playerLevel * 5 + 45) * (1 - (levelDif / getZD(playerLevel)));
+            }
+        }
+        if (xp == 0) {
+            return 0;
+        }
+        return (int) Math.floor(xp + 0.5);
+    }
+
+
+    public static Npc.NpcLevelColor getLevelColor(int playerLevel, int npcLevel) {
+        if (playerLevel + 5 <= npcLevel) {
+            return Npc.NpcLevelColor.RED;
+        } else {
+            switch (npcLevel - playerLevel) {
+                case 4:
+                case 3:
+                    return Npc.NpcLevelColor.ORANGE;
+                case 2:
+                case 1:
+                case 0:
+                case -1:
+                case -2:
+                    return Npc.NpcLevelColor.YELLOW;
+                default:
+                    if (playerLevel <= 5) {
+                        return Npc.NpcLevelColor.GREEN;
+                    } else {
+                        if (playerLevel <= 50) {
+                            if (npcLevel <= (playerLevel - 5 - Math.floor(playerLevel / 10))) {
+                                return Npc.NpcLevelColor.WHITE;
+                            } else {
+                                return Npc.NpcLevelColor.GREEN;
+                            }
+                        } else {
+                            // Player is over level 50
+                            if (npcLevel <= (playerLevel - 1 - Math.floor(playerLevel / 5))) {
+                                return Npc.NpcLevelColor.WHITE;
+                            } else {
+                                return Npc.NpcLevelColor.GREEN;
+                            }
+                        }
+                    }
+            }
+        }
+    }
+
+    private static int getZD(int lvl) {
+        if (lvl <= 7) {
+            return 5;
+        }
+        if (lvl <= 9) {
+            return 6;
+        }
+        if (lvl <= 11) {
+            return 7;
+        }
+        if (lvl <= 15) {
+            return 8;
+        }
+        if (lvl <= 19) {
+            return 9;
+        }
+        if (lvl <= 29) {
+            return 11;
+        }
+        if (lvl <= 39) {
+            return 12;
+        }
+        if (lvl <= 49) {
+            return 13;
+        }
+        if (lvl <= 59) {
+            return 14;
+        }
+        if (lvl <= 69) {
+            return 15;
+        }
+        if (lvl <= 79) {
+            return 16;
+        }
+        if (lvl <= 89) {
+            return 17;
+        }
+        if (lvl <= 99) {
+            return 18;
+        } else {
+            return 19;
+        }
+    }
+
 }
diff --git a/src/main/java/com/comandante/creeper/player/Levels.java b/src/main/java/com/comandante/creeper/player/Levels.java
index 123a27ebc3be3692f481d82eb4a3dbd531d90695..6eb9ca510aa63b96063b78b3283f7cbbc011e5c4 100644
--- a/src/main/java/com/comandante/creeper/player/Levels.java
+++ b/src/main/java/com/comandante/creeper/player/Levels.java
@@ -5,7 +5,7 @@ import static java.lang.StrictMath.sqrt;
 
 public class Levels {
 
-    private static double CONSTANT_MODIFIER = 0.005;
+    private static double CONSTANT_MODIFIER = 0.02;
 
     public static long getLevel(long experience) {
         double v = CONSTANT_MODIFIER * sqrt(experience);
diff --git a/src/main/java/com/comandante/creeper/player/NpcAggroCountDown.java b/src/main/java/com/comandante/creeper/player/NpcAggroCountDown.java
new file mode 100644
index 0000000000000000000000000000000000000000..f507cad0ea3e9c9c95ffa0fbd79bb5f72f9ea6e6
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/player/NpcAggroCountDown.java
@@ -0,0 +1,38 @@
+package com.comandante.creeper.player;
+
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.npc.Npc;
+import com.comandante.creeper.server.Color;
+import com.comandante.creeper.world.Room;
+import com.google.common.util.concurrent.AbstractExecutionThreadService;
+
+public class NpcAggroCountDown extends AbstractExecutionThreadService {
+
+    private final int delaySeconds;
+    private final GameManager gameManager;
+    private final Player player;
+    private final Npc npc;
+    private final Room originalRoom;
+
+    public NpcAggroCountDown(int delaySeconds, GameManager gameManager, Player player, Npc npc, Room originalRoom) {
+        this.delaySeconds = delaySeconds;
+        this.gameManager = gameManager;
+        this.player = player;
+        this.npc = npc;
+        this.originalRoom = originalRoom;
+    }
+
+    @Override
+    protected void run() throws Exception {
+        try {
+            Thread.sleep(delaySeconds * 1000);
+            if (!player.getCurrentRoom().getRoomId().equals(originalRoom.getRoomId())) {
+                return;
+            }
+            gameManager.writeToPlayerCurrentRoom(player.getPlayerId(), player.getPlayerName() + " has " + Color.BOLD_ON + Color.RED + "angered" + Color.RESET + " a " + npc.getColorName() + "\r\n");
+            player.addActiveFight(npc);
+        } finally {
+            this.shutDown();
+        }
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/player/Player.java b/src/main/java/com/comandante/creeper/player/Player.java
old mode 100755
new mode 100644
index 4ed831d1e9de4311b904a64eeecd51f953a2f955..2dcfb547e9241c3e6534f4412bd3a4ca42f36ad5
--- a/src/main/java/com/comandante/creeper/player/Player.java
+++ b/src/main/java/com/comandante/creeper/player/Player.java
@@ -2,6 +2,8 @@ package com.comandante.creeper.player;
 
 
 import com.codahale.metrics.Meter;
+import com.comandante.creeper.CreeperUtils;
+import com.comandante.creeper.Items.ForageManager;
 import com.comandante.creeper.Items.Item;
 import com.comandante.creeper.Items.ItemType;
 import com.comandante.creeper.Main;
@@ -10,39 +12,43 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.managers.SentryManager;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.npc.NpcStatsChangeBuilder;
+import com.comandante.creeper.npc.Temperament;
 import com.comandante.creeper.server.Color;
 import com.comandante.creeper.spells.Effect;
 import com.comandante.creeper.stat.Stats;
 import com.comandante.creeper.stat.StatsBuilder;
 import com.comandante.creeper.stat.StatsHelper;
 import com.comandante.creeper.world.Room;
-import com.google.common.base.Optional;
 import com.google.common.collect.*;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.log4j.Logger;
 import org.jboss.netty.channel.Channel;
 import org.nocrala.tools.texttablefmt.BorderStyle;
 import org.nocrala.tools.texttablefmt.ShownBorders;
+import org.nocrala.tools.texttablefmt.Table;
 
 import java.text.NumberFormat;
 import java.util.*;
+import java.util.stream.Collectors;
 
 public class Player extends CreeperEntity {
 
+    private static final Logger log = Logger.getLogger(Player.class);
+    private final GameManager gameManager;
+    private final String playerId;
+    private final Interner<String> interner = Interners.newWeakInterner();
+    private final Random random = new Random();
     private String playerName;
     private Channel channel;
-    private Optional<String> returnDirection = Optional.absent();
-    private final GameManager gameManager;
+    private Optional<String> returnDirection = Optional.empty();
     private Room currentRoom;
     private SortedMap<Long, ActiveFight> activeFights = Collections.synchronizedSortedMap(new TreeMap<Long, ActiveFight>());
-    private final String playerId;
     private Set<CoolDown> coolDowns = Collections.synchronizedSet(new HashSet<CoolDown>());
-    private final Interner<String> interner = Interners.newWeakInterner();
-    private final Random random = new Random();
     private int tickBucket = 0;
     private int fightTickBucket = 0;
-
-    private static final Logger log = Logger.getLogger(Player.class);
+    private List<NpcAggroCountDown> aggroCountDowns = Lists.newArrayList();
+    private boolean hasAlertedNpc;
+    private Room previousRoom;
 
     public Player(String playerName, GameManager gameManager) {
         this.playerName = playerName;
@@ -94,22 +100,21 @@ public class Player extends CreeperEntity {
     }
 
     private void processFightRounds() {
-        for (ActiveFight activeFight : activeFights.values()) {
-            doFightRound(activeFight);
-        }
+        activeFights.forEach((aLong, activeFight) -> doFightRound(activeFight));
     }
 
     private void processRegens() {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = gameManager.getPlayerManager().getPlayerMetadata(playerId);
             Stats stats = getPlayerStatsWithEquipmentAndLevel();
-            if (!isActive(CoolDownType.DEATH)) {
-                if (playerMetadata.getStats().getCurrentHealth() < stats.getMaxHealth()) {
-                    updatePlayerHealth((int) (stats.getMaxHealth() * .05), null);
-                }
-                if (playerMetadata.getStats().getCurrentMana() < stats.getMaxMana()) {
-                    addMana((int) (stats.getMaxMana() * .03));
-                }
+            if (isActive(CoolDownType.NPC_FIGHT) || isActive(CoolDownType.DEATH)) {
+                return;
+            }
+            if (playerMetadata.getStats().getCurrentHealth() < stats.getMaxHealth()) {
+                updatePlayerHealth((int) (stats.getMaxHealth() * .05), null);
+            }
+            if (playerMetadata.getStats().getCurrentMana() < stats.getMaxMana()) {
+                addMana((int) (stats.getMaxMana() * .03));
             }
         }
     }
@@ -160,9 +165,8 @@ public class Player extends CreeperEntity {
                 CoolDown death = new CoolDown(CoolDownType.DEATH);
                 addCoolDown(death);
                 gameManager.writeToPlayerCurrentRoom(getPlayerId(), getPlayerName() + " is now dead." + "\r\n");
-                PlayerMovement playerMovement = new PlayerMovement(this, gameManager.getRoomManager().getPlayerCurrentRoom(this).get().getRoomId(), GameManager.LOBBY_ID, null, "vanished into the ether.", "");
+                PlayerMovement playerMovement = new PlayerMovement(this, gameManager.getRoomManager().getPlayerCurrentRoom(this).get().getRoomId(), GameManager.LOBBY_ID, "vanished into the ether.", "");
                 movePlayer(playerMovement);
-                gameManager.currentRoomLogic(getPlayerId());
                 String prompt = gameManager.buildPrompt(playerId);
                 gameManager.getChannelUtils().write(getPlayerId(), prompt, true);
             }
@@ -195,6 +199,18 @@ public class Player extends CreeperEntity {
         return false;
     }
 
+    public Room getPreviousRoom() {
+        synchronized (interner.intern(playerId)) {
+            return previousRoom;
+        }
+    }
+
+    public void setPreviousRoom(Room previousRoom) {
+        synchronized (interner.intern(playerId)) {
+            this.previousRoom = previousRoom;
+        }
+    }
+
     private void addHealth(long addAmt, PlayerMetadata playerMetadata) {
         long currentHealth = playerMetadata.getStats().getCurrentHealth();
         Stats statsModifier = getPlayerStatsWithEquipmentAndLevel();
@@ -247,6 +263,14 @@ public class Player extends CreeperEntity {
         }
     }
 
+    private PlayerMetadata getPlayerMetadata() {
+        return gameManager.getPlayerManager().getPlayerMetadata(playerId);
+    }
+
+    private void savePlayerMetadata(PlayerMetadata playerMetadata) {
+        gameManager.getPlayerManager().savePlayerMetadata(playerMetadata);
+    }
+
     public long getCurrentHealth() {
         synchronized (interner.intern(playerId)) {
             return gameManager.getPlayerManager().getPlayerMetadata(playerId).getStats().getCurrentHealth();
@@ -289,43 +313,59 @@ public class Player extends CreeperEntity {
         }
     }
 
-    public void resetEffects(){
-        synchronized (interner){
+    public void resetEffects() {
+        synchronized (interner) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
             playerMetadata.resetEffects();
             gameManager.getPlayerManager().savePlayerMetadata(playerMetadata);
         }
     }
 
-    public void addLockerInventoryId(String entityId) {
+    public void addLearnedSpellByName(String spellName) {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
-            playerMetadata.addLockerEntityId(entityId);
+            playerMetadata.addLearnedSpellByName(spellName);
             savePlayerMetadata(playerMetadata);
         }
     }
 
-    public void removeLockerInventoryId(String lockerInventoryId) {
+    public boolean doesHaveSpellLearned(String spellName) {
+        PlayerMetadata playerMetadata = getPlayerMetadata();
+        if (playerMetadata.getLearnedSpells() == null || playerMetadata.getLearnedSpells().length == 0) {
+            return false;
+        }
+        List<String> learnedSpells = Arrays.asList(playerMetadata.getLearnedSpells());
+        return learnedSpells.contains(spellName);
+    }
+
+    public void removeLearnedSpellByName(String spellName) {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
-            playerMetadata.removeLockerEntityId(lockerInventoryId);
+            playerMetadata.removeLearnedSpellByName(spellName);
             savePlayerMetadata(playerMetadata);
         }
     }
 
-    public void addEquipmentId(String equipmentId) {
+    public List<String> getLearnedSpells() {
+        PlayerMetadata playerMetadata = getPlayerMetadata();
+        return Lists.newArrayList(playerMetadata.getLearnedSpells());
+    }
+
+    public boolean isActiveAlertNpcStatus() {
         synchronized (interner.intern(playerId)) {
-            PlayerMetadata playerMetadata = getPlayerMetadata();
-            playerMetadata.addEquipmentEntityId(equipmentId);
-            savePlayerMetadata(playerMetadata);
+            return hasAlertedNpc;
         }
     }
 
-    public void removeEquipmentId(String equipmentId) {
+    public void setIsActiveAlertNpcStatus() {
         synchronized (interner.intern(playerId)) {
-            PlayerMetadata playerMetadata = getPlayerMetadata();
-            playerMetadata.removeEquipmentEntityId(equipmentId);
-            savePlayerMetadata(playerMetadata);
+            hasAlertedNpc = true;
+        }
+    }
+
+    public void removeActiveAlertStatus() {
+        synchronized (interner.intern(playerId)) {
+            hasAlertedNpc = false;
         }
     }
 
@@ -337,6 +377,13 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public void transferItemToLocker(String inventoryId) {
+        synchronized (interner.intern(playerId)) {
+            removeInventoryId(inventoryId);
+            addLockerInventoryId(inventoryId);
+        }
+    }
+
     public void removeInventoryId(String inventoryId) {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -345,13 +392,24 @@ public class Player extends CreeperEntity {
         }
     }
 
-    public void transferItemToLocker(String inventoryId) {
+    public void addLockerInventoryId(String entityId) {
         synchronized (interner.intern(playerId)) {
-            removeInventoryId(inventoryId);
-            addLockerInventoryId(inventoryId);
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            playerMetadata.addLockerEntityId(entityId);
+            savePlayerMetadata(playerMetadata);
         }
     }
 
+    public void addNpcKillLog(String npcName) {
+        gameManager.getEventProcessor().addEvent(() -> {
+            synchronized (interner.intern(playerId)) {
+                PlayerMetadata playerMetadata = getPlayerMetadata();
+                playerMetadata.addNpcKill(npcName);
+                savePlayerMetadata(playerMetadata);
+            }
+        });
+    }
+
     public void transferItemFromLocker(String entityId) {
         synchronized (interner.intern(playerId)) {
             if (gameManager.acquireItem(this, entityId)) {
@@ -360,6 +418,14 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public void removeLockerInventoryId(String lockerInventoryId) {
+        synchronized (interner.intern(playerId)) {
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            playerMetadata.removeLockerEntityId(lockerInventoryId);
+            savePlayerMetadata(playerMetadata);
+        }
+    }
+
     public void updatePlayerMana(int amount) {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -386,17 +452,6 @@ public class Player extends CreeperEntity {
         return coolDowns;
     }
 
-    public boolean isActive(CoolDownType coolDownType) {
-        for (CoolDown c : coolDowns) {
-            if (c.getCoolDownType().equals(coolDownType)) {
-                if (c.isActive()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     public boolean isActiveCoolDown() {
         return coolDowns.size() > 0;
     }
@@ -411,6 +466,17 @@ public class Player extends CreeperEntity {
         return false;
     }
 
+    public boolean isActive(CoolDownType coolDownType) {
+        for (CoolDown c : coolDowns) {
+            if (c.getCoolDownType().equals(coolDownType)) {
+                if (c.isActive()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     public boolean isActiveSpellCoolDown(String spellName) {
         for (CoolDown coolDown : coolDowns) {
             if (coolDown.getName().equalsIgnoreCase(spellName)) {
@@ -437,10 +503,6 @@ public class Player extends CreeperEntity {
         gameManager.getChannelUtils().write(playerId, prompt, true);
     }
 
-    public String getPlayerName() {
-        return playerName;
-    }
-
     public String getPlayerId() {
         return playerId;
     }
@@ -469,6 +531,12 @@ public class Player extends CreeperEntity {
         this.currentRoom = currentRoom;
     }
 
+    public Map<String, Long> getNpcKillLog() {
+        ImmutableMap.Builder<String, Long> builder = ImmutableMap.builder();
+        getPlayerMetadata().getNpcKillLog().forEach(builder::put);
+        return builder.build();
+    }
+
     public void movePlayer(PlayerMovement playerMovement) {
         synchronized (interner.intern(playerId)) {
             Room sourceRoom = gameManager.getRoomManager().getRoom(playerMovement.getSourceRoomId());
@@ -481,16 +549,40 @@ public class Player extends CreeperEntity {
                 gameManager.getChannelUtils().write(next.getPlayerId(), sb.toString(), true);
             }
             destinationRoom.addPresentPlayer(playerMovement.getPlayer().getPlayerId());
+            setPreviousRoom(currentRoom);
             playerMovement.getPlayer().setCurrentRoom(destinationRoom);
             for (Player next : gameManager.getRoomManager().getPresentPlayers(destinationRoom)) {
                 if (next.getPlayerId().equals(playerMovement.getPlayer().getPlayerId())) {
                     continue;
                 }
-                gameManager.getChannelUtils().write(next.getPlayerId(), playerMovement.getPlayer().getPlayerName() + " arrived.", true);
+            }
+            setReturnDirection(java.util.Optional.of(playerMovement.getReturnDirection()));
+            gameManager.currentRoomLogic(playerId, gameManager.getRoomManager().getRoom(playerMovement.getDestinationRoomId()));
+            gameManager.getRoomManager().getRoom(playerMovement.getDestinationRoomId());
+            if (!isActive(CoolDownType.DEATH)) {
+                processNpcAggro();
             }
         }
     }
 
+    private void processNpcAggro() {
+        List<Npc> aggresiveRoomNpcs = currentRoom.getNpcIds().stream()
+                .map(npcId -> gameManager.getEntityManager().getNpcEntity(npcId))
+                .filter(npc -> npc.getTemperament().equals(Temperament.AGGRESSIVE))
+                .filter(npc -> {Npc.NpcLevelColor levelColor = npc.getLevelColor((int) Levels.getLevel(getPlayerStatsWithEquipmentAndLevel().getExperience()));
+                    return !levelColor.equals(Npc.NpcLevelColor.WHITE);
+                })
+                .collect(Collectors.toList());
+
+        aggresiveRoomNpcs.forEach(npc -> {
+            gameManager.writeToPlayerCurrentRoom(getPlayerId(), getPlayerName() + " has alerted a " + npc.getColorName() + "\r\n");
+            gameManager.getChannelUtils().write(playerId, "You can return to your previous location by typing \"back\"" + "\r\n");
+            setIsActiveAlertNpcStatus();
+            NpcAggroCountDown npcAggroCountDown = new NpcAggroCountDown(5, gameManager, this, npc, currentRoom);
+            npcAggroCountDown.startAsync();
+        });
+    }
+
     public Item getInventoryItem(String itemKeyword) {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -508,54 +600,8 @@ public class Player extends CreeperEntity {
         }
     }
 
-    public List<Item> getInventory() {
-        synchronized (interner.intern(playerId)) {
-            PlayerMetadata playerMetadata = getPlayerMetadata();
-            List<Item> inventoryItems = Lists.newArrayList();
-            List<String> inventory = playerMetadata.getInventory();
-            if (inventory != null) {
-                for (String itemId : inventory) {
-                    Item itemEntity = gameManager.getEntityManager().getItemEntity(itemId);
-                    if (itemEntity == null) {
-                        log.info("Orphaned inventoryId:" + itemId + " player: " + getPlayerName());
-                        continue;
-                    }
-                    inventoryItems.add(itemEntity);
-                }
-            }
-            Collections.sort(inventoryItems, new Comparator<Item>() {
-                @Override
-                public int compare(final Item object1, final Item object2) {
-                    return object1.getItemName().compareTo(object2.getItemName());
-                }
-            });
-            return inventoryItems;
-        }
-    }
-
-    public List<Item> getLockerInventory() {
-        synchronized (interner.intern(playerId)) {
-            PlayerMetadata playerMetadata = getPlayerMetadata();
-            List<Item> inventoryItems = Lists.newArrayList();
-            List<String> inventory = playerMetadata.getLockerInventory();
-            if (inventory != null) {
-                for (String itemId : inventory) {
-                    Item itemEntity = gameManager.getEntityManager().getItemEntity(itemId);
-                    if (itemEntity == null) {
-                        log.info("Orphaned inventoryId:" + itemId + " player: " + getPlayerName());
-                        continue;
-                    }
-                    inventoryItems.add(itemEntity);
-                }
-            }
-            Collections.sort(inventoryItems, new Comparator<Item>() {
-                @Override
-                public int compare(final Item object1, final Item object2) {
-                    return object1.getItemName().compareTo(object2.getItemName());
-                }
-            });
-            return inventoryItems;
-        }
+    public String getPlayerName() {
+        return playerName;
     }
 
     public List<String> getRolledUpLockerInventory() {
@@ -599,6 +645,31 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public List<Item> getLockerInventory() {
+        synchronized (interner.intern(playerId)) {
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            List<Item> inventoryItems = Lists.newArrayList();
+            List<String> inventory = playerMetadata.getLockerInventory();
+            if (inventory != null) {
+                for (String itemId : inventory) {
+                    Item itemEntity = gameManager.getEntityManager().getItemEntity(itemId);
+                    if (itemEntity == null) {
+                        log.info("Orphaned inventoryId:" + itemId + " player: " + getPlayerName());
+                        continue;
+                    }
+                    inventoryItems.add(itemEntity);
+                }
+            }
+            Collections.sort(inventoryItems, new Comparator<Item>() {
+                @Override
+                public int compare(final Item object1, final Item object2) {
+                    return object1.getItemName().compareTo(object2.getItemName());
+                }
+            });
+            return inventoryItems;
+        }
+    }
+
     public List<String> getRolledUpIntentory() {
         synchronized (interner.intern(playerId)) {
             List<String> rolledUp = Lists.newArrayList();
@@ -640,6 +711,31 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public List<Item> getInventory() {
+        synchronized (interner.intern(playerId)) {
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            List<Item> inventoryItems = Lists.newArrayList();
+            List<String> inventory = playerMetadata.getInventory();
+            if (inventory != null) {
+                for (String itemId : inventory) {
+                    Item itemEntity = gameManager.getEntityManager().getItemEntity(itemId);
+                    if (itemEntity == null) {
+                        log.info("Orphaned inventoryId:" + itemId + " player: " + getPlayerName());
+                        continue;
+                    }
+                    inventoryItems.add(itemEntity);
+                }
+            }
+            Collections.sort(inventoryItems, new Comparator<Item>() {
+                @Override
+                public int compare(final Item object1, final Item object2) {
+                    return object1.getItemName().compareTo(object2.getItemName());
+                }
+            });
+            return inventoryItems;
+        }
+    }
+
     public Set<Item> getEquipment() {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -704,6 +800,44 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public void addEquipmentId(String equipmentId) {
+        synchronized (interner.intern(playerId)) {
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            playerMetadata.addEquipmentEntityId(equipmentId);
+            savePlayerMetadata(playerMetadata);
+        }
+    }
+
+    public void removeEquipmentId(String equipmentId) {
+        synchronized (interner.intern(playerId)) {
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            playerMetadata.removeEquipmentEntityId(equipmentId);
+            savePlayerMetadata(playerMetadata);
+        }
+    }
+
+    public String getLookString() {
+        StringBuilder sb = new StringBuilder();
+        Stats origStats = gameManager.getStatsModifierFactory().getStatsModifier(this);
+        Stats modifiedStats = getPlayerStatsWithEquipmentAndLevel();
+        Stats diffStats = StatsHelper.getDifference(modifiedStats, origStats);
+        sb.append(Color.MAGENTA + "-+=[ " + Color.RESET).append(playerName).append(Color.MAGENTA + " ]=+- " + Color.RESET).append("\r\n");
+        sb.append("Level ").append(Levels.getLevel(origStats.getExperience())).append("\r\n");
+        sb.append("Foraging Level ").append(ForageManager.getLevel(modifiedStats.getForaging())).append("\r\n");
+        sb.append(Color.MAGENTA + "Equip--------------------------------" + Color.RESET).append("\r\n");
+        sb.append(buildEquipmentString()).append("\r\n");
+        sb.append(Color.MAGENTA + "Stats--------------------------------" + Color.RESET).append("\r\n");
+        sb.append(gameManager.buildLookString(playerName, modifiedStats, diffStats)).append("\r\n");
+        PlayerMetadata playerMetadata = getPlayerMetadata();
+        if (playerMetadata.getEffects() != null && playerMetadata.getEffects().size() > 0) {
+            sb.append(Color.MAGENTA + "Effects--------------------------------" + Color.RESET).append("\r\n");
+            sb.append(buldEffectsString()).append("\r\n");
+        }
+        StringBuilder finalString = new StringBuilder();
+        Lists.newArrayList(sb.toString().split("[\\r\\n]+")).forEach(s -> finalString.append(CreeperUtils.trimTrailingBlanks(s)).append("\r\n"));
+        return finalString.toString();
+    }
+
     public Stats getPlayerStatsWithEquipmentAndLevel() {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -733,28 +867,8 @@ public class Player extends CreeperEntity {
         }
     }
 
-    public String getLookString() {
-        StringBuilder sb = new StringBuilder();
-        Stats origStats = gameManager.getStatsModifierFactory().getStatsModifier(this);
-        Stats modifiedStats = getPlayerStatsWithEquipmentAndLevel();
-        Stats diffStats = StatsHelper.getDifference(modifiedStats, origStats);
-        sb.append(Color.MAGENTA + "-+=[ " + Color.RESET).append(playerName).append(Color.MAGENTA + " ]=+- " + Color.RESET).append("\r\n");
-        sb.append("Level ").append(Levels.getLevel(origStats.getExperience())).append("\r\n");
-        sb.append("Foraging Level ").append(gameManager.getForageManager().getLevel(modifiedStats.getForaging())).append("\r\n");
-        sb.append(Color.MAGENTA + "Equip--------------------------------" + Color.RESET).append("\r\n");
-        sb.append(buildEquipmentString()).append("\r\n");
-        sb.append(Color.MAGENTA + "Stats--------------------------------" + Color.RESET).append("\r\n");
-        sb.append(gameManager.buildLookString(playerName, modifiedStats, diffStats)).append("\r\n");
-        PlayerMetadata playerMetadata = getPlayerMetadata();
-        if (playerMetadata.getEffects() != null && playerMetadata.getEffects().size() > 0) {
-            sb.append(Color.MAGENTA + "Effects--------------------------------" + Color.RESET).append("\r\n");
-            sb.append(buldEffectsString()).append("\r\n");
-        }
-        return sb.toString();
-    }
-
     public String buildEquipmentString() {
-        org.nocrala.tools.texttablefmt.Table t = new org.nocrala.tools.texttablefmt.Table(2, BorderStyle.CLASSIC_COMPATIBLE,
+        Table t = new Table(2, BorderStyle.CLASSIC_COMPATIBLE,
                 ShownBorders.NONE);
         t.setColumnWidth(0, 16, 20);
 
@@ -771,6 +885,7 @@ public class Player extends CreeperEntity {
         return t.render();
     }
 
+    /* FIGHT FIGHT FIGHT FIGHT */
 
     public String buldEffectsString() {
         PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -790,8 +905,6 @@ public class Player extends CreeperEntity {
         return Character.toUpperCase(line.charAt(0)) + line.substring(1);
     }
 
-    /* FIGHT FIGHT FIGHT FIGHT */
-
     public void removeAllActiveFights() {
         synchronized (interner.intern(playerId)) {
             Iterator<Map.Entry<Long, ActiveFight>> iterator = activeFights.entrySet().iterator();
@@ -828,24 +941,11 @@ public class Player extends CreeperEntity {
         return getPlayerMetadata().getPlayerSettings();
     }
 
-    public void removeActiveFight(Npc npc) {
-        synchronized (interner.intern(playerId)) {
-            Iterator<Map.Entry<Long, ActiveFight>> iterator = activeFights.entrySet().iterator();
-            while (iterator.hasNext()) {
-                Map.Entry<Long, ActiveFight> next = iterator.next();
-                if (next.getValue().getNpcId().equals(npc.getEntityId())) {
-                    if (next.getValue().isPrimary) {
-                    }
-                    iterator.remove();
-                }
-            }
-        }
-    }
-
     public boolean addActiveFight(Npc npc) {
         synchronized (interner.intern(playerId)) {
             if (gameManager.getEntityManager().getNpcEntity(npc.getEntityId()) != null) {
                 if (!doesActiveFightExist(npc)) {
+                    addCoolDown(new CoolDown(CoolDownType.NPC_FIGHT));
                     ActiveFight activeFight = new ActiveFight(npc.getEntityId(), false);
                     activeFights.put(System.nanoTime(), activeFight);
                     return true;
@@ -870,6 +970,20 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public void removeActiveFight(Npc npc) {
+        synchronized (interner.intern(playerId)) {
+            Iterator<Map.Entry<Long, ActiveFight>> iterator = activeFights.entrySet().iterator();
+            while (iterator.hasNext()) {
+                Map.Entry<Long, ActiveFight> next = iterator.next();
+                if (next.getValue().getNpcId().equals(npc.getEntityId())) {
+                    if (next.getValue().isPrimary) {
+                    }
+                    iterator.remove();
+                }
+            }
+        }
+    }
+
     public boolean isActiveFights() {
         synchronized (interner.intern(playerId)) {
             if (activeFights.size() > 0) {
@@ -935,18 +1049,19 @@ public class Player extends CreeperEntity {
             }
             if (damageToVictim > 0) {
                 if (randInt(0, 100) > 95) {
-                   final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + Color.YELLOW + "The " + npc.getColorName() + " was caught off guard by the attack!" + "+" + NumberFormat.getNumberInstance(Locale.US).format(damageToVictim) + Color.RESET + Color.BOLD_ON + Color.RED + " DAMAGE" + Color.RESET + " done to " + npc.getColorName();
-                   npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-(damageToVictim*3)).createStats());
-                   npcStatsChangeBuilder.setDamageStrings(Arrays.asList(fightMsg)); 
+                    long criticalDamage = damageToVictim * 3;
+                    final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + Color.YELLOW + "The " + npc.getColorName() + " was caught off guard by the attack! " + "+" + NumberFormat.getNumberInstance(Locale.US).format(criticalDamage) + Color.RESET + Color.BOLD_ON + Color.RED + " DAMAGE" + Color.RESET + " done to " + npc.getColorName();
+                    npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-(criticalDamage)).createStats());
+                    npcStatsChangeBuilder.setDamageStrings(Collections.singletonList(fightMsg));
                 } else {
                     final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + Color.YELLOW + "+" + NumberFormat.getNumberInstance(Locale.US).format(damageToVictim) + Color.RESET + Color.BOLD_ON + Color.RED + " DAMAGE" + Color.RESET + " done to " + npc.getColorName();
                     npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-damageToVictim).createStats());
-                    npcStatsChangeBuilder.setDamageStrings(Arrays.asList(fightMsg));
+                    npcStatsChangeBuilder.setDamageStrings(Collections.singletonList(fightMsg));
                 }
             } else {
                 final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + "You MISS " + npc.getName() + "!";
                 npcStatsChangeBuilder.setStats(new StatsBuilder().setCurrentHealth(-damageToVictim).createStats());
-                npcStatsChangeBuilder.setDamageStrings(Arrays.asList(fightMsg));
+                npcStatsChangeBuilder.setDamageStrings(Collections.singletonList(fightMsg));
             }
         }
         if (this.doesActiveFightExist(npc)) {
@@ -955,12 +1070,12 @@ public class Player extends CreeperEntity {
             if (randInt(0, 100) < chanceToHitBack) {
                 final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + npc.getColorName() + Color.BOLD_ON + Color.RED + " DAMAGES" + Color.RESET + " you for " + Color.RED + "-" + NumberFormat.getNumberInstance(Locale.US).format(damageBack) + Color.RESET;
                 npcStatsChangeBuilder.setPlayerStatsChange(new StatsBuilder().setCurrentHealth(-damageBack).createStats());
-                npcStatsChangeBuilder.setPlayerDamageStrings(Arrays.asList(fightMsg));
+                npcStatsChangeBuilder.setPlayerDamageStrings(Collections.singletonList(fightMsg));
 
             } else {
                 final String fightMsg = Color.BOLD_ON + Color.RED + "[attack] " + Color.RESET + npc.getColorName() + Color.BOLD_ON + Color.CYAN + " MISSES" + Color.RESET + " you!";
                 npcStatsChangeBuilder.setPlayerStatsChange(new StatsBuilder().setCurrentHealth(0).createStats());
-                npcStatsChangeBuilder.setPlayerDamageStrings(Arrays.asList(fightMsg));
+                npcStatsChangeBuilder.setPlayerDamageStrings(Collections.singletonList(fightMsg));
             }
             npc.addNpcDamage(npcStatsChangeBuilder.createNpcStatsChange());
         }
@@ -993,6 +1108,10 @@ public class Player extends CreeperEntity {
         return random.nextInt((max - min) + 1) + min;
     }
 
+    public Interner<String> getInterner() {
+        return interner;
+    }
+
     class ActiveFight {
         private final String npcId;
         private boolean isPrimary;
@@ -1015,16 +1134,4 @@ public class Player extends CreeperEntity {
         }
 
     }
-
-    private PlayerMetadata getPlayerMetadata() {
-        return gameManager.getPlayerManager().getPlayerMetadata(playerId);
-    }
-
-    private void savePlayerMetadata(PlayerMetadata playerMetadata) {
-        gameManager.getPlayerManager().savePlayerMetadata(playerMetadata);
-    }
-
-    public Interner<String> getInterner() {
-        return interner;
-    }
 }
diff --git a/src/main/java/com/comandante/creeper/player/PlayerManager.java b/src/main/java/com/comandante/creeper/player/PlayerManager.java
index 7c790e73c91104807fe12baffdeb122cab39ae75..8b3c33120c40ad728528ad69451b8c85391b733f 100644
--- a/src/main/java/com/comandante/creeper/player/PlayerManager.java
+++ b/src/main/java/com/comandante/creeper/player/PlayerManager.java
@@ -18,14 +18,10 @@ import static com.codahale.metrics.MetricRegistry.name;
 
 public class PlayerManager {
 
-    private ConcurrentHashMap<String, Player> players = new ConcurrentHashMap<String, Player>();
-    private HTreeMap<String, PlayerMetadata> playerMetadataStore;
     private final DB db;
     private final SessionManager sessionManager;
-
-    public SessionManager getSessionManager() {
-        return sessionManager;
-    }
+    private ConcurrentHashMap<String, Player> players = new ConcurrentHashMap<String, Player>();
+    private HTreeMap<String, PlayerMetadata> playerMetadataStore;
 
     public PlayerManager(DB db, SessionManager sessionManager) {
         this.db = db;
@@ -39,12 +35,8 @@ public class PlayerManager {
         this.sessionManager = sessionManager;
     }
 
-    public PlayerMetadata getPlayerMetadata(String playerId) {
-        PlayerMetadata playerMetadata = playerMetadataStore.get(playerId);
-        if (playerMetadata == null) {
-            return playerMetadata;
-        }
-        return new PlayerMetadata(playerMetadata);
+    public SessionManager getSessionManager() {
+        return sessionManager;
     }
 
     public void savePlayerMetadata(PlayerMetadata playerMetadata) {
@@ -55,18 +47,14 @@ public class PlayerManager {
         return players.put(player.getPlayerId(), player);
     }
 
-    public Player getPlayerByUsername(String username) {
-        return getPlayer(new String(Base64.encodeBase64(username.getBytes())));
-    }
-
-    public Player getPlayer(String playerId) {
-        return players.get(playerId);
-    }
-
     public Iterator<java.util.Map.Entry<String, Player>> getPlayers() {
         return players.entrySet().iterator();
     }
 
+    public Map<String, Player> getAllPlayersMap() {
+        return players;
+    }
+
     public void removePlayer(String username) {
         Player player = getPlayerByUsername(username);
         if (player.getChannel() != null && player.getChannel().isConnected()) {
@@ -75,6 +63,14 @@ public class PlayerManager {
         players.remove(player.getPlayerId());
     }
 
+    public Player getPlayerByUsername(String username) {
+        return getPlayer(new String(Base64.encodeBase64(username.getBytes())));
+    }
+
+    public Player getPlayer(String playerId) {
+        return players.get(playerId);
+    }
+
     public boolean doesPlayerExist(String username) {
         return players.containsKey(new String(Base64.encodeBase64(username.getBytes())));
     }
@@ -89,6 +85,14 @@ public class PlayerManager {
         }
     }
 
+    public PlayerMetadata getPlayerMetadata(String playerId) {
+        PlayerMetadata playerMetadata = playerMetadataStore.get(playerId);
+        if (playerMetadata == null) {
+            return playerMetadata;
+        }
+        return new PlayerMetadata(playerMetadata);
+    }
+
     public boolean hasAnyOfRoles(Player player, Set<PlayerRole> checkRoles) {
         PlayerMetadata playerMetadata = getPlayerMetadata(player.getPlayerId());
         Set<PlayerRole> playerRoleSet = playerMetadata.getPlayerRoleSet();
@@ -104,6 +108,14 @@ public class PlayerManager {
         return false;
     }
 
+    public void createAllGauges() {
+        Iterator<Map.Entry<String, PlayerMetadata>> iterator = playerMetadataStore.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<String, PlayerMetadata> next = iterator.next();
+            createGauges(next.getValue());
+        }
+    }
+
     public void createGauges(final PlayerMetadata playerMetadata) {
         String guageName = name(PlayerManager.class, playerMetadata.getPlayerName(), "gold");
         if (!doesGaugeExist(guageName)) {
@@ -139,14 +151,6 @@ public class PlayerManager {
         }
     }
 
-    public void createAllGauges() {
-        Iterator<Map.Entry<String, PlayerMetadata>> iterator = playerMetadataStore.entrySet().iterator();
-        while (iterator.hasNext()) {
-            Map.Entry<String, PlayerMetadata> next = iterator.next();
-            createGauges(next.getValue());
-        }
-    }
-
     private boolean doesGaugeExist(String name) {
         return Main.metrics.getGauges().containsKey(name);
     }
diff --git a/src/main/java/com/comandante/creeper/player/PlayerMetadata.java b/src/main/java/com/comandante/creeper/player/PlayerMetadata.java
index 44004e8ad0f3137e8a051dea1ac6b4c2288150b7..6dc035654bbc452cd0ea43dfa8dbef2945ca6d09 100644
--- a/src/main/java/com/comandante/creeper/player/PlayerMetadata.java
+++ b/src/main/java/com/comandante/creeper/player/PlayerMetadata.java
@@ -24,8 +24,10 @@ public class PlayerMetadata implements Serializable {
     private List<String> effects;
     private boolean isMarkedForDelete;
     private Map<String, String> playerSettings;
+    private String[] learnedSpells;
+    private Map<String, Long> npcKillLog;
 
-    public PlayerMetadata(String playerName, String password, String playerId, Stats stats, int gold, Set<PlayerRole> playerRoleSet, String[] playerEquipment, int goldInBank) {
+    public PlayerMetadata(String playerName, String password, String playerId, Stats stats, int gold, Set<PlayerRole> playerRoleSet, String[] playerEquipment, int goldInBank, String[] learnedSpells, Map<String, Long> npcKillLog) {
         this.playerName = playerName;
         this.password = password;
         this.playerId = playerId;
@@ -34,6 +36,8 @@ public class PlayerMetadata implements Serializable {
         this.playerRoleSet = playerRoleSet;
         this.playerEquipment = playerEquipment;
         this.goldInBank = goldInBank;
+        this.learnedSpells = learnedSpells;
+        this.npcKillLog = npcKillLog;
     }
 
     public PlayerMetadata(PlayerMetadata playerMetadata) {
@@ -59,9 +63,15 @@ public class PlayerMetadata implements Serializable {
             this.effects = Lists.newArrayList(playerMetadata.getEffects());
         }
         if (playerMetadata.playerSettings != null) {
-            this.playerSettings = new HashMap<String, String>(playerMetadata.getPlayerSettings());
+            this.playerSettings = new HashMap<>(playerMetadata.getPlayerSettings());
+        }
+        if (playerMetadata.learnedSpells != null) {
+            this.learnedSpells = Arrays.copyOf(playerMetadata.learnedSpells, playerMetadata.learnedSpells.length);
         }
         this.isMarkedForDelete = new Boolean(playerMetadata.isMarkedForDelete);
+        if (playerMetadata.npcKillLog != null) {
+            this.npcKillLog = new HashMap<>(playerMetadata.getNpcKillLog());
+        }
     }
 
     public List<String> getInventory() {
@@ -92,6 +102,19 @@ public class PlayerMetadata implements Serializable {
         lockerInventory.add(newEntityId);
     }
 
+    protected void addNpcKill(String npcName) {
+        if (this.npcKillLog == null) {
+            npcKillLog = Maps.newHashMap();
+        }
+        if (npcKillLog.containsKey(npcName)) {
+            Long aLong = npcKillLog.get(npcName);
+            Long newLong = aLong + 1;
+            npcKillLog.put(npcName, newLong);
+        } else {
+            npcKillLog.put(npcName, 1L);
+        }
+    }
+
 
     protected void removeLockerEntityId(String newEntityId) {
         lockerInventory.remove(newEntityId);
@@ -101,6 +124,27 @@ public class PlayerMetadata implements Serializable {
         inventory.remove(itemId);
     }
 
+    protected void addLearnedSpellByName(String spellName) {
+        if (learnedSpells == null) {
+            learnedSpells = new String[0];
+        }
+        String[] result = Arrays.copyOf(learnedSpells, learnedSpells.length + 1);
+        result[learnedSpells.length] = spellName;
+        this.learnedSpells = result;
+    }
+
+    protected void removeLearnedSpellByName(String spellName) {
+        List<String> learnedSpellsKeep = new ArrayList<String>(Arrays.asList(learnedSpells));
+        learnedSpellsKeep.remove(spellName);
+        String[] newSpells = new String[learnedSpellsKeep.size()];
+        int i = 0;
+        for (String id : learnedSpellsKeep) {
+            newSpells[i] = id;
+            i++;
+        }
+        this.learnedSpells = newSpells;
+    }
+
     protected void addEquipmentEntityId(String equipmentItemId) {
         if (playerEquipment == null) {
             playerEquipment = new String[0];
@@ -161,6 +205,17 @@ public class PlayerMetadata implements Serializable {
         return goldInBank;
     }
 
+    public String[] getLearnedSpells() {
+        return learnedSpells;
+    }
+
+    public Map<String, Long> getNpcKillLog() {
+        if (this.npcKillLog == null) {
+            npcKillLog = Maps.newHashMap();
+        }
+        return npcKillLog;
+    }
+
     protected void setGold(long amt) {
         this.gold = amt;
     }
diff --git a/src/main/java/com/comandante/creeper/player/PlayerMovement.java b/src/main/java/com/comandante/creeper/player/PlayerMovement.java
index bd9509f87d362fd490b39f567af21465401c07b4..faf8f9d321e3fbed52349c20b5ddd300624619ef 100644
--- a/src/main/java/com/comandante/creeper/player/PlayerMovement.java
+++ b/src/main/java/com/comandante/creeper/player/PlayerMovement.java
@@ -7,20 +7,17 @@ public class PlayerMovement {
     private final Player player;
     private final Integer sourceRoomId;
     private final Integer destinationRoomId;
-    private final MovementCommand command;
     private final String roomExitMessage;
     private final String returnDirection;
 
     public PlayerMovement(Player player,
                           Integer sourceRoomId,
                           Integer destinationRoomId,
-                          MovementCommand command,
                           String roomExitMessage,
                           String returnDirection) {
         this.player = player;
         this.sourceRoomId = sourceRoomId;
         this.destinationRoomId = destinationRoomId;
-        this.command = command;
         this.roomExitMessage = roomExitMessage;
         this.returnDirection = returnDirection;
 
@@ -45,8 +42,4 @@ public class PlayerMovement {
     public String getRoomExitMessage() {
         return roomExitMessage;
     }
-
-    public MovementCommand getCommand() {
-        return command;
-    }
 }
diff --git a/src/main/java/com/comandante/creeper/player/PlayerStats.java b/src/main/java/com/comandante/creeper/player/PlayerStats.java
index 30b706ddeb80ac83339ea083cb3e4050e95a1f0d..f13ba40e5f2497b18318faa5c9d7d41cf85d1352 100644
--- a/src/main/java/com/comandante/creeper/player/PlayerStats.java
+++ b/src/main/java/com/comandante/creeper/player/PlayerStats.java
@@ -14,8 +14,8 @@ public class PlayerStats {
             .setMeleSkill(10)
             .setCurrentHealth(100)
             .setMaxHealth(100)
-            .setWeaponRatingMin(10)
-            .setWeaponRatingMax(20)
+            .setWeaponRatingMin(3)
+            .setWeaponRatingMax(5)
             .setNumberOfWeaponRolls(1)
             .setExperience(0)
             .setCurrentMana(100)
diff --git a/src/main/java/com/comandante/creeper/server/ChannelCommunicationUtils.java b/src/main/java/com/comandante/creeper/server/ChannelCommunicationUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..092ab5b417b57074d7741aebc5256a6c2424219e
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/server/ChannelCommunicationUtils.java
@@ -0,0 +1,13 @@
+package com.comandante.creeper.server;
+
+import com.comandante.creeper.player.Player;
+import com.comandante.creeper.player.PlayerManager;
+import com.comandante.creeper.world.RoomManager;
+
+public interface ChannelCommunicationUtils {
+
+        void write(String playerId, String message);
+
+        void write(String playerId, String message, boolean leadingBlankLine);
+
+}
diff --git a/src/main/java/com/comandante/creeper/server/ChannelUtils.java b/src/main/java/com/comandante/creeper/server/ChannelUtils.java
index 231925d16ef8a6bc203b6808247d23c1559661f5..177c9a2792323152e451e111daf33adaa1b7aee0 100644
--- a/src/main/java/com/comandante/creeper/server/ChannelUtils.java
+++ b/src/main/java/com/comandante/creeper/server/ChannelUtils.java
@@ -4,7 +4,7 @@ import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerManager;
 import com.comandante.creeper.world.RoomManager;
 
-public class ChannelUtils {
+public class ChannelUtils implements ChannelCommunicationUtils {
 
     private final PlayerManager playerManager;
     private final RoomManager roomManager;
diff --git a/src/main/java/com/comandante/creeper/server/CreeperAuthenticationHandler.java b/src/main/java/com/comandante/creeper/server/CreeperAuthenticationHandler.java
index 1a994c726e57d7d15e1c8ccacd70b0c852bb51d6..fb7d6ea1228c5f1aeb3d88c286614f6604d09ac3 100644
--- a/src/main/java/com/comandante/creeper/server/CreeperAuthenticationHandler.java
+++ b/src/main/java/com/comandante/creeper/server/CreeperAuthenticationHandler.java
@@ -14,28 +14,29 @@ public class CreeperAuthenticationHandler extends SimpleChannelUpstreamHandler {
     private final GameManager gameManager;
     private final CreeperAuthenticator creeperAuthenticator;
     private static final Logger log = Logger.getLogger(CreeperAuthenticationHandler.class);
-    private static final String LOGO = "                          /[-])//  ___\n\r" +
-            "                     __ --\\ `_/~--|  / \\\n\r" +
-            "                   /_-/~~--~~ /~~~\\\\_\\ /\\\n\r" +
-            "                   |  |___|===|_-- | \\ \\ \\\n\r" +
-            " _/~~~~~~~~|~~\\,   ---|---\\___/----|  \\/\\-\\\n\r" +
-            " ~\\________|__/   / // \\__ |  ||  / | |   | |\n\r" +
-            "          ,~-|~~~~~\\--, | \\|--|/~|||  |   | |\n\r" +
-            "          [3-|____---~~ _--'==;/ _,   |   |_|\n\r" +
-            "                      /   /\\__|_/  \\  \\__/--/\n\r" +
-            "                     /---/_\\  -___/ |  /,--|\n\r" +
-            "                     /  /\\/~--|   | |  \\///\n\r" +
-            "                    /  / |-__ \\    |/\n\r" +
-            "                   |--/ /      |-- | \\\n\r" +
-            "                  \\^~~\\\\/\\      \\   \\/- _\n\r" +
-            "                   \\    |  \\     |~~\\~~| \\\n\r" +
-            "                    \\    \\  \\     \\   \\  | \\\n\r" +
-            "                      \\    \\ |     \\   \\    \\\n\r" +
-            "                       |~~|\\/\\|     \\   \\   |\n\r" +
-            "                      |   |/         \\_--_- |\\\n\r" +
-            "                      |  /            /   |/\\/\n\r" +
-            "                       ~~             /  /\n\r" +
-            "                                     |__/\n\r";
+    private static final String LOGO = "                      __gggrgM**M#mggg__\n" +
+            "                 __wgNN@\"B*P\"\"mp\"\"@d#\"@N#Nw__\n" +
+            "               _g#@0F_a*F#  _*F9m_ ,F9*__9NG#g_\n" +
+            "            _mN#F  aM\"    #p\"    !q@    9NL \"9#Qu_\n" +
+            "           g#MF _pP\"L  _g@\"9L_  _g\"\"#__  g\"9w_ 0N#p\n" +
+            "         _0F jL*\"   7_wF     #_gF     9gjF   \"bJ  9h_\n" +
+            "        j#  gAF    _@NL     _g@#_      J@u_    2#_  #_\n" +
+            "       ,FF_#\" 9_ _#\"  \"b_  g@   \"hg  _#\"  !q_ jF \"*_09_\n" +
+            "       F N\"    #p\"      Ng@       `#g\"      \"w@    \"# t\n" +
+            "      j p#    g\"9_     g@\"9_      gP\"#_     gF\"q    Pb L\n" +
+            "      0J  k _@   9g_ j#\"   \"b_  j#\"   \"b_ _d\"   q_ g  ##\n" +
+            "      #F  `NF     \"#g\"       \"Md\"       5N#      9W\"  j#\n" +
+            "      #k  jFb_    g@\"q_     _*\"9m_     _*\"R_    _#Np  J#\n" +
+            "      tApjF  9g  J\"   9M_ _m\"    9%_ _*\"   \"#  gF  9_jNF\n" +
+            "       k`N    \"q#       9g@        #gF       ##\"    #\"j\n" +
+            "       `_0q_   #\"q_    _&\"9p_    _g\"`L_    _*\"#   jAF,'\n" +
+            "        9# \"b_j   \"b_ g\"    *g _gF    9_ g#\"  \"L_*\"qNF\n" +
+            "         \"b_ \"#_    \"NL      _B#      _I@     j#\" _#\"\n" +
+            "           NM_0\"*g_ j\"\"9u_  gP  q_  _w@ ]_ _g*\"F_g@\n" +
+            "            \"NNh_ !w#_   9#g\"    \"m*\"   _#*\" _dN@\"\n" +
+            "               9##g_0@q__ #\"4_  j*\"k __*NF_g#@P\"\n" +
+            "                 \"9NN#gIPNL_ \"b@\" _2M\"Lg#N@F\"\n" +
+            "                     \"\"P@*NN#gEZgNN@#@P\"\"\n";
 
     public CreeperAuthenticationHandler(GameManager gameManager) {
         this.gameManager = gameManager;
@@ -105,7 +106,7 @@ public class CreeperAuthenticationHandler extends SimpleChannelUpstreamHandler {
         String message = (String) e.getMessage();
         CreeperSession creeperSession = (CreeperSession) ctx.getAttachment();
         if (creeperSession.getState().equals(CreeperSession.State.promptedForUsername)) {
-            creeperSession.setUsername(Optional.of(message.replaceAll("[^a-zA-Z0-9]", "")));
+            creeperSession.setUsername(java.util.Optional.of(message.replaceAll("[^a-zA-Z0-9]", "")));
             if (creeperSession.getUsername().isPresent() && creeperSession.getUsername().get().equals("tupac")) {
                 gameManager.getNewUserRegistrationManager().newUserRegistrationFlow(creeperSession, e);
                 return;
diff --git a/src/main/java/com/comandante/creeper/server/CreeperSession.java b/src/main/java/com/comandante/creeper/server/CreeperSession.java
index a653149ab4cf94f5d395f30ef0818e43acb9ff08..4ba519500a9b777148e22c119d1a6f84873ee2d2 100644
--- a/src/main/java/com/comandante/creeper/server/CreeperSession.java
+++ b/src/main/java/com/comandante/creeper/server/CreeperSession.java
@@ -11,12 +11,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 public class CreeperSession {
 
-    private Optional<String> username = Optional.absent();
+    private java.util.Optional<String> username = java.util.Optional.empty();
     private Optional<String> password = Optional.absent();
     private boolean isAuthed = false;
     private AtomicBoolean isAbleToDoAbility = new AtomicBoolean(false);
-    private Optional<CreeperEntry<UUID, Command>> grabMultiLineInput = Optional.absent();
-    private Optional<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>> grabMerchant = Optional.absent();
+    private java.util.Optional<CreeperEntry<UUID, Command>> grabMultiLineInput = java.util.Optional.empty();
+    private java.util.Optional<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>> grabMerchant = java.util.Optional.empty();
     private String lastMessage;
     private final Long initialLoginTime;
     private Long lastActivity;
@@ -46,11 +46,11 @@ public class CreeperSession {
         this.lastMessage = lastMessage;
     }
 
-    public Optional<String> getUsername() {
+    public java.util.Optional<String> getUsername() {
         return username;
     }
 
-    public void setUsername(Optional<String> username) {
+    public void setUsername(java.util.Optional<String> username) {
         this.username = username;
     }
 
@@ -86,11 +86,11 @@ public class CreeperSession {
         return this.isAbleToDoAbility.get();
     }
 
-    public Optional<CreeperEntry<UUID, Command>> getGrabMultiLineInput() {
+    public java.util.Optional<CreeperEntry<UUID, Command>> getGrabMultiLineInput() {
         return grabMultiLineInput;
     }
 
-    public void setGrabMultiLineInput(Optional<CreeperEntry<UUID, Command>> grabMultiLineInput) {
+    public void setGrabMultiLineInput(java.util.Optional<CreeperEntry<UUID, Command>> grabMultiLineInput) {
         this.grabMultiLineInput = grabMultiLineInput;
     }
 
@@ -102,11 +102,11 @@ public class CreeperSession {
         this.isAbleToDoAbility = isAbleToDoAbility;
     }
 
-    public Optional<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>> getGrabMerchant() {
+    public java.util.Optional<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>> getGrabMerchant() {
         return grabMerchant;
     }
 
-    public void setGrabMerchant(Optional<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>> grabMerchant) {
+    public void setGrabMerchant(java.util.Optional<CreeperEntry<Merchant, SimpleChannelUpstreamHandler>> grabMerchant) {
         this.grabMerchant = grabMerchant;
     }
 
diff --git a/src/main/java/com/comandante/creeper/server/GameAuth.java b/src/main/java/com/comandante/creeper/server/GameAuth.java
index 46763438f68810e2358d25e6ca46f78fa433b7ed..c6a31b57cf25c7c3f68aace516a97ea753bfb81c 100644
--- a/src/main/java/com/comandante/creeper/server/GameAuth.java
+++ b/src/main/java/com/comandante/creeper/server/GameAuth.java
@@ -5,9 +5,10 @@ import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerMetadata;
 import com.comandante.creeper.world.Room;
-import com.google.common.base.Optional;
 import org.jboss.netty.channel.Channel;
 
+import java.util.Optional;
+
 public class GameAuth implements CreeperAuthenticator {
 
     private final GameManager gameManager;
diff --git a/src/main/java/com/comandante/creeper/server/GossipCache.java b/src/main/java/com/comandante/creeper/server/GossipCache.java
index 402c7c8762bde3b4ffa5ee72e576b337a4733e27..3a22c1bc0ab1fb969938cab8eb94fe7f8b8e5859 100644
--- a/src/main/java/com/comandante/creeper/server/GossipCache.java
+++ b/src/main/java/com/comandante/creeper/server/GossipCache.java
@@ -4,7 +4,9 @@ import com.comandante.creeper.managers.GameManager;
 import com.google.api.client.util.Lists;
 import com.google.common.collect.EvictingQueue;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
 
 public class GossipCache {
 
@@ -22,12 +24,8 @@ public class GossipCache {
 
     public List<String> getRecent(int size) {
         List<String> recent = Lists.newArrayList();
-        List<String> currentEntries = Lists.newArrayList();
-        Iterator<String> iterator = evictingQueue.iterator();
-        while (iterator.hasNext()) {
-            String next = iterator.next();
-            currentEntries.add(next);
-        }
+        List<String> currentEntries = evictingQueue.stream().collect(Collectors.toList());
+
         Collections.reverse(currentEntries);
         int i = 0;
         for (String s : currentEntries) {
diff --git a/src/main/java/com/comandante/creeper/spawner/NpcSpawner.java b/src/main/java/com/comandante/creeper/spawner/NpcSpawner.java
old mode 100755
new mode 100644
index 07b9908938cdf80bcfd60ddb8310eb7030e63785..b479ec54ef7b5ef6a8170169f99f658b03c3ccb7
--- a/src/main/java/com/comandante/creeper/spawner/NpcSpawner.java
+++ b/src/main/java/com/comandante/creeper/spawner/NpcSpawner.java
@@ -9,13 +9,12 @@ import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.npc.NpcBuilder;
 import com.comandante.creeper.world.Area;
 import com.comandante.creeper.world.Room;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterators;
-import com.google.common.collect.Lists;
 
-import java.util.ArrayList;
+import java.util.List;
 import java.util.Random;
 import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 public class NpcSpawner extends CreeperEntity {
 
@@ -69,7 +68,7 @@ public class NpcSpawner extends CreeperEntity {
     }
 
     private void createAndAddItem(Area spawnArea) {
-        ArrayList<Room> rooms = Lists.newArrayList(Iterators.filter(gameManager.getRoomManager().getRoomsByArea(spawnArea).iterator(), getRoomsWithRoom()));
+        List<Room> rooms = gameManager.getRoomManager().getRoomsByArea(spawnArea).stream().filter(getRoomsWithRoom()).collect(Collectors.toList());
         Room room = rooms.get(random.nextInt(rooms.size()));
         NpcBuilder npcBuilder = new NpcBuilder(npc);
         Npc newNpc = npcBuilder.createNpc();
@@ -80,23 +79,30 @@ public class NpcSpawner extends CreeperEntity {
         Main.metrics.counter(MetricRegistry.name(NpcSpawner.class, npc.getName() + "-spawn")).inc();
     }
 
+    private Predicate<Room> getRoomsWithRoomNew() {
+        return room -> {
+            int count = room.getNpcIds().stream().filter(npcId -> {
+                Npc npcEntity = gameManager.getEntityManager().getNpcEntity(npcId);
+                return npcEntity.getName().equals(npc.getName());
+            }).collect(Collectors.toList()).size();
+            return count < spawnRule.getMaxPerRoom();
+        };
+    }
+
     private Predicate<Room> getRoomsWithRoom() {
-        return new Predicate<Room>() {
-            @Override
-            public boolean apply(Room room) {
-                int count = 0;
-                Set<String> npcIds = room.getNpcIds();
-                for (String npcId : npcIds) {
-                    Npc npcEntity = gameManager.getEntityManager().getNpcEntity(npcId);
-                    if (npcEntity.getName().equals(npc.getName())) {
-                        count++;
-                    }
-                }
-                if (count < spawnRule.getMaxPerRoom()) {
-                    return true;
+        return room -> {
+            int count = 0;
+            Set<String> npcIds = room.getNpcIds();
+            for (String npcId : npcIds) {
+                Npc npcEntity = gameManager.getEntityManager().getNpcEntity(npcId);
+                if (npcEntity.getName().equals(npc.getName())) {
+                    count++;
                 }
-                return false;
             }
+            if (count < spawnRule.getMaxPerRoom()) {
+                return true;
+            }
+            return false;
         };
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/comandante/creeper/spells/LightningSpell.java b/src/main/java/com/comandante/creeper/spells/LightningSpell.java
index b9fc556bf337c1cb1f70c6d188b9d2cbc3f30412..b986b516ab3d09fba5a9882dec3ed3a34c9e0595 100644
--- a/src/main/java/com/comandante/creeper/spells/LightningSpell.java
+++ b/src/main/java/com/comandante/creeper/spells/LightningSpell.java
@@ -18,7 +18,7 @@ import static com.comandante.creeper.server.Color.BOLD_ON;
 
 public class LightningSpell extends Spell {
 
-    private final static String NAME = BOLD_ON + Color.YELLOW + "lightning" + Color.RESET + " bolt";
+    public final static String NAME = BOLD_ON + Color.YELLOW + "lightning" + Color.RESET + " bolt";
     private final static String DESCRIPTION = "A powerful bolt of lightning.";
     private final static Set<String> validTriggers = new HashSet<String>(Arrays.asList(new String[]
                     {"lightning", "lightning bolt", "l", NAME}
@@ -52,7 +52,7 @@ public class LightningSpell extends Spell {
     public void attackSpell(Set<String> npcIds, Player player) {
         Stats playerStats = player.getPlayerStatsWithEquipmentAndLevel();
         long willpower = playerStats.getWillpower();
-        long i = 500 + (willpower * 3);
+        long i = 20 + (willpower * 3);
         this.setEffects(Sets.newHashSet(burnEffect.setApplyStatsOnTick(new StatsBuilder().setCurrentHealth(-i).createStats()).createEffect()));
         super.attackSpell(npcIds, player);
     }
diff --git a/src/main/java/com/comandante/creeper/spells/Spell.java b/src/main/java/com/comandante/creeper/spells/Spell.java
index b89c3acd7c13ad7595d16aee9013033673a88468..f702e299525961f3dacdadf8a4a2247c8eeddd60 100644
--- a/src/main/java/com/comandante/creeper/spells/Spell.java
+++ b/src/main/java/com/comandante/creeper/spells/Spell.java
@@ -247,5 +247,4 @@ public abstract class Spell {
     interface SpellExecute {
         public void executeNpc(GameManager gameManager, Npc npc, Player player);
     }
-
 }
diff --git a/src/main/java/com/comandante/creeper/spells/SpellRegistry.java b/src/main/java/com/comandante/creeper/spells/SpellTriggerRegistry.java
similarity index 79%
rename from src/main/java/com/comandante/creeper/spells/SpellRegistry.java
rename to src/main/java/com/comandante/creeper/spells/SpellTriggerRegistry.java
index 1b4ad8b1189653c20adfa7700b67ae735139a5ac..e393bc683287f06c14f1def2ee410ebe16004107 100644
--- a/src/main/java/com/comandante/creeper/spells/SpellRegistry.java
+++ b/src/main/java/com/comandante/creeper/spells/SpellTriggerRegistry.java
@@ -5,9 +5,11 @@ import com.google.common.collect.Maps;
 
 import java.util.Map;
 
-public class SpellRegistry {
+public class SpellTriggerRegistry {
 
     public static final Map<String, Spell> spellMap = Maps.newHashMap();
+    public static final Map<String, Spell> spellNameMap = Maps.newHashMap();
+
 
     public static void addSpell(Spell spell) {
         for (String trigger : spell.getValidTriggers()) {
@@ -18,4 +20,5 @@ public class SpellRegistry {
     public static Spell getSpell(String trigger) {
         return spellMap.get(trigger);
     }
+
 }
diff --git a/src/main/java/com/comandante/creeper/world/BasicRoom.java b/src/main/java/com/comandante/creeper/world/BasicRoom.java
index c51ad18eef6a743f2ace303c08b6f25727347af1..16136730787928bba43ac69efcabf902c5273c7c 100644
--- a/src/main/java/com/comandante/creeper/world/BasicRoom.java
+++ b/src/main/java/com/comandante/creeper/world/BasicRoom.java
@@ -1,10 +1,10 @@
 package com.comandante.creeper.world;
 
 import com.comandante.creeper.managers.GameManager;
-import com.google.common.base.Optional;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 public class BasicRoom extends Room {
diff --git a/src/main/java/com/comandante/creeper/world/BasicRoomBuilder.java b/src/main/java/com/comandante/creeper/world/BasicRoomBuilder.java
index fb3d5685752927839d4fd0d71d831d1e2d5c8f32..d6483170627bf72becd9041a59de309f1dc8e4a8 100644
--- a/src/main/java/com/comandante/creeper/world/BasicRoomBuilder.java
+++ b/src/main/java/com/comandante/creeper/world/BasicRoomBuilder.java
@@ -1,25 +1,25 @@
 package com.comandante.creeper.world;
 
 import com.comandante.creeper.managers.GameManager;
-import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 public class BasicRoomBuilder {
     private Integer roomId;
     private String roomTitle;
     private Integer floorId;
-    private Optional<Integer> northId = Optional.absent();
-    private Optional<Integer> southId = Optional.absent();
-    private Optional<Integer> eastId = Optional.absent();
-    private Optional<Integer> westId = Optional.absent();
-    private Optional<Integer> upId = Optional.absent();
-    private Optional<Integer> downId = Optional.absent();
+    private Optional<Integer> northId = Optional.empty();
+    private Optional<Integer> southId = Optional.empty();
+    private Optional<Integer> eastId = Optional.empty();
+    private Optional<Integer> westId = Optional.empty();
+    private Optional<Integer> upId = Optional.empty();
+    private Optional<Integer> downId = Optional.empty();
     private List<RemoteExit> enterExits = Lists.newArrayList();
     private String roomDescription;
     private Set<String> roomTags = Sets.newConcurrentHashSet();
diff --git a/src/main/java/com/comandante/creeper/world/MapMatrix.java b/src/main/java/com/comandante/creeper/world/MapMatrix.java
index 4fa0ffd4376f1da14b0860bca4f75c4fcf09e7a7..2ff949178f884984f870139762abe029d86a1fba 100644
--- a/src/main/java/com/comandante/creeper/world/MapMatrix.java
+++ b/src/main/java/com/comandante/creeper/world/MapMatrix.java
@@ -171,7 +171,6 @@ public class MapMatrix {
         };
     }
 
-
     public String getCsv() {
         StringBuilder sb = new StringBuilder();
         for (List<Integer> list : matrix) {
@@ -262,7 +261,7 @@ public class MapMatrix {
                 roomOpts.add(0);
             }
         }
-        return new MapMatrix(lists, Maps.<Integer, Set<RemoteExit>>newHashMap());
+        return new MapMatrix(lists, Maps.newHashMap());
     }
 
     public String renderMap(Integer roomId, RoomManager roomManager) {
@@ -270,18 +269,14 @@ public class MapMatrix {
         Iterator<List<Integer>> rows = getRows();
         while (rows.hasNext()) {
             List<Integer> next = rows.next();
-            Iterator<String> transform = Iterators.transform(next.iterator(), MapsManager.render(roomId, roomManager));
-            while (transform.hasNext()) {
-                String s = transform.next();
-                sb.append(s);
-            }
+            next.stream().map(MapsManager.render(roomId, roomManager)).forEach(sb::append);
             sb.append("\r\n");
         }
         return sb.toString();
     }
 
     public void addRow(boolean startOfArray) {
-        ArrayList<Integer> newRow = Lists.<Integer>newArrayList();
+        ArrayList<Integer> newRow = Lists.newArrayList();
         for (int i = 0; i < matrix.get(0).size(); i++) {
             newRow.add(0);
         }
diff --git a/src/main/java/com/comandante/creeper/world/MapsManager.java b/src/main/java/com/comandante/creeper/world/MapsManager.java
index 5a4e94075b3d594902889a5d23ac0b3db1997209..ea2c8e10bfb32cc249b35d3ccffa51e84578ab12 100644
--- a/src/main/java/com/comandante/creeper/world/MapsManager.java
+++ b/src/main/java/com/comandante/creeper/world/MapsManager.java
@@ -5,15 +5,15 @@ import com.comandante.creeper.CreeperConfiguration;
 import com.comandante.creeper.Main;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.server.Color;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
 import com.google.common.collect.Maps;
 import org.apache.log4j.Logger;
 
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.function.Function;
 
 import static com.codahale.metrics.MetricRegistry.name;
 
@@ -24,7 +24,7 @@ public class MapsManager {
     private final CreeperConfiguration creeperConfiguration;
     private final ExecutorService mapGeneratorService = Executors.newFixedThreadPool(1);
     private static final Logger log = Logger.getLogger(GameManager.class);
-    private final com.codahale.metrics.Timer ticktime = Main.metrics.timer(name(MapsManager.class, "generate_all_maps_time"));
+    private final Timer ticktime = Main.metrics.timer(name(MapsManager.class, "generate_all_maps_time"));
 
     public MapsManager(CreeperConfiguration creeperConfiguration, RoomManager roomManager) {
         this.roomManager = roomManager;
@@ -36,7 +36,7 @@ public class MapsManager {
         Timer.Context time = ticktime.time();
         int maxRows = creeperConfiguration.defaultMapSize;
         int maxColumns = creeperConfiguration.defaultMapSize;
-        Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRoomsIterator();
         while (rooms.hasNext()) {
             Map.Entry<Integer, Room> next = rooms.next();
             Integer roomId = next.getValue().getRoomId();
@@ -57,29 +57,26 @@ public class MapsManager {
     }
 
     public static Function<Integer, String> render(final Integer currentroomId, final RoomManager roomManager) {
-        return new Function<Integer, String>() {
-            @Override
-            public String apply(Integer roomId) {
-                Room room = roomManager.getRoom(roomId);
-                if (roomId > 0) {
-                    if (roomId.equals(currentroomId)) {
-                        return "[" + Color.BOLD_ON + Color.RED + "*" + Color.RESET + "]";
-                    } else if (roomId.equals(1)) {
-                        return "[" + Color.BOLD_ON + Color.BLUE + "L" + Color.RESET + "]";
-                    } else if (room.getMerchants().size() > 0) {
-                        return "[" + Color.YELLOW + "m" + Color.RESET + "]";
-                    }  else if (room.getEnterExits().size() > 0) {
-                        return "[" + Color.CYAN + "e" + Color.RESET + "]";
-                    } else if (room.getUpId().isPresent()) {
-                        return "[" + Color.GREEN + "^" + Color.RESET + "]";
-                    } else if (room.getDownId().isPresent()) {
-                        return "[" + Color.GREEN + "v" + Color.RESET + "]";
-                    } else {
-                        return "[ ]";
-                    }
+        return roomId -> {
+            Room room = roomManager.getRoom(roomId);
+            if (roomId > 0) {
+                if (roomId.equals(currentroomId)) {
+                    return "[" + Color.BOLD_ON + Color.RED + "*" + Color.RESET + "]";
+                } else if (roomId.equals(1)) {
+                    return "[" + Color.BOLD_ON + Color.BLUE + "L" + Color.RESET + "]";
+                } else if (room.getMerchants().size() > 0) {
+                    return "[" + Color.YELLOW + "m" + Color.RESET + "]";
+                }  else if (room.getEnterExits().size() > 0) {
+                    return "[" + Color.CYAN + "e" + Color.RESET + "]";
+                } else if (room.getUpId().isPresent()) {
+                    return "[" + Color.GREEN + "^" + Color.RESET + "]";
+                } else if (room.getDownId().isPresent()) {
+                    return "[" + Color.GREEN + "v" + Color.RESET + "]";
                 } else {
-                    return "   ";
+                    return "[ ]";
                 }
+            } else {
+                return "   ";
             }
         };
     }
diff --git a/src/main/java/com/comandante/creeper/world/Room.java b/src/main/java/com/comandante/creeper/world/Room.java
index 0a65d6f031b6bef57489b4713f6bb8f6a918922c..aadb5b44b338e3760bda9980e859c7322a2899ec 100644
--- a/src/main/java/com/comandante/creeper/world/Room.java
+++ b/src/main/java/com/comandante/creeper/world/Room.java
@@ -7,15 +7,13 @@ import com.comandante.creeper.entity.CreeperEntity;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.merchant.Merchant;
 import com.comandante.creeper.spawner.ItemSpawner;
-import com.google.common.base.Optional;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
-import java.lang.reflect.GenericArrayType;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 
 public abstract class Room extends CreeperEntity {
@@ -45,7 +43,7 @@ public abstract class Room extends CreeperEntity {
     private final Set<String> itemIds = Sets.newConcurrentHashSet();
     private List<ItemSpawner> itemSpawners = Lists.newArrayList();
     private Set<Area> areas = Sets.newConcurrentHashSet();
-    private Optional<String> mapData = Optional.absent();
+    private Optional<String> mapData = Optional.empty();
     private final Set<String> roomTags;
     private final Set<Merchant> merchants = Sets.newConcurrentHashSet();
     private Map<ItemType, Forage> forages = Maps.newHashMap();
@@ -179,7 +177,7 @@ public abstract class Room extends CreeperEntity {
         return npcIds;
     }
 
-    protected java.util.Set<String> getPresentPlayerIds() {
+    protected Set<String> getPresentPlayerIds() {
         // terrible null pointers will result if you call this shit directly.
         // People sign off and cause problems
         return presentPlayerIds;
@@ -187,6 +185,7 @@ public abstract class Room extends CreeperEntity {
 
     public void addPresentPlayer(String playerId) {
         presentPlayerIds.add(playerId);
+
     }
 
     public void removePresentPlayer(String playerId) {
diff --git a/src/main/java/com/comandante/creeper/world/RoomManager.java b/src/main/java/com/comandante/creeper/world/RoomManager.java
index 7c5c6806aac938d8205ac8fac7d5ff73d07fd9b7..121cf7ad38954efc5fa99d0eecc3cd4348660d09 100644
--- a/src/main/java/com/comandante/creeper/world/RoomManager.java
+++ b/src/main/java/com/comandante/creeper/world/RoomManager.java
@@ -4,35 +4,26 @@ import com.comandante.creeper.merchant.Merchant;
 import com.comandante.creeper.npc.Npc;
 import com.comandante.creeper.player.Player;
 import com.comandante.creeper.player.PlayerManager;
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 
 public class RoomManager {
 
     private final PlayerManager playerManager;
+    private ConcurrentHashMap<Integer, Room> rooms = new ConcurrentHashMap<>();
 
     public RoomManager(PlayerManager playerManager) {
         this.playerManager = playerManager;
     }
 
-    private ConcurrentHashMap<Integer, Room> rooms = new ConcurrentHashMap<Integer, Room>();
-
     public void addRoom(Room room) {
         rooms.put(room.getRoomId(), room);
     }
 
-    public Room getRoom(Integer roomId) {
-        return rooms.get(roomId);
-    }
-
     public Set<Player> getPresentPlayers(Room room) {
         Set<String> presentPlayerIds = room.getPresentPlayerIds();
         Set<Player> players = Sets.newHashSet();
@@ -47,7 +38,7 @@ public class RoomManager {
 
     public Optional<List<Integer>> getRoomsForTag(String tag) {
         List<Integer> matchedRooms = Lists.newArrayList();
-        Iterator<Map.Entry<Integer, Room>> rooms = getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms = getRoomsIterator();
         while (rooms.hasNext()) {
             Map.Entry<Integer, Room> next = rooms.next();
             if (next.getValue().getRoomTags().contains(tag)) {
@@ -57,15 +48,21 @@ public class RoomManager {
 
         if (matchedRooms.size() > 0) {
             return Optional.of(matchedRooms);
-        } else {
-            return Optional.absent();
-        }
+        } else return Optional.empty();
+    }
+
+    public Iterator<Map.Entry<Integer, Room>> getRoomsIterator() {
+        return rooms.entrySet().iterator();
     }
 
     public void addMerchant(Integer roomId, Merchant merchant) {
         getRoom(roomId).addMerchant(merchant);
     }
 
+    public Room getRoom(Integer roomId) {
+        return rooms.get(roomId);
+    }
+
     public void tagRoom(Integer roomId, String tag) {
         getRoom(roomId).addTag(tag);
     }
@@ -74,13 +71,13 @@ public class RoomManager {
         return getRoom(roomId).getRoomTags();
     }
 
-    public Iterator<java.util.Map.Entry<Integer, Room>> getRooms() {
-        return rooms.entrySet().iterator();
+    public Map<Integer, Room> getrooms() {
+        return rooms;
     }
 
     public Set<Room> getRoomsByFloorId(Integer floorId) {
         Set<Room> rooms = Sets.newHashSet();
-        Iterator<Map.Entry<Integer, Room>> rooms1 = getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms1 = getRoomsIterator();
         while (rooms1.hasNext()) {
             Map.Entry<Integer, Room> next = rooms1.next();
             if (next.getValue().getFloorId().equals(floorId)) {
@@ -90,8 +87,15 @@ public class RoomManager {
         return rooms;
     }
 
+    public Optional<Room> getPlayerCurrentRoom(Player player) {
+        if (player.getCurrentRoom() != null) {
+            return Optional.of(player.getCurrentRoom());
+        }
+        return getPlayerCurrentRoom(player.getPlayerId());
+    }
+
     public Optional<Room> getPlayerCurrentRoom(String playerId) {
-        Iterator<Map.Entry<Integer, Room>> rooms = getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms = getRoomsIterator();
         while (rooms.hasNext()) {
             Map.Entry<Integer, Room> next = rooms.next();
             Room room = next.getValue();
@@ -101,14 +105,7 @@ public class RoomManager {
                 }
             }
         }
-        return Optional.absent();
-    }
-
-    public Optional<Room> getPlayerCurrentRoom(Player player) {
-        if (player.getCurrentRoom() != null) {
-            return Optional.of(player.getCurrentRoom());
-        }
-        return getPlayerCurrentRoom(player.getPlayerId());
+        return Optional.empty();
     }
 
     public Optional<Room> getNpcCurrentRoom(Npc npc) {
@@ -118,7 +115,7 @@ public class RoomManager {
 
     public Set<Room> getRoomsByArea(Area area) {
         Set<Room> rooms = Sets.newHashSet();
-        Iterator<Map.Entry<Integer, Room>> rooms1 = getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms1 = getRoomsIterator();
         while (rooms1.hasNext()) {
             Map.Entry<Integer, Room> next = rooms1.next();
             if (next.getValue().getAreas().contains(area)) {
@@ -129,7 +126,7 @@ public class RoomManager {
     }
 
     public boolean doesRoomIdExist(Integer roomId) {
-        Iterator<Map.Entry<Integer, Room>> rooms1 = getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms1 = getRoomsIterator();
         Set<Integer> roomIds = Sets.newHashSet();
         while (rooms1.hasNext()) {
             Map.Entry<Integer, Room> next = rooms1.next();
@@ -141,7 +138,7 @@ public class RoomManager {
     }
 
     public Room getRoomByItemId(String itemId) {
-        Iterator<Map.Entry<Integer, Room>> rooms = getRooms();
+        Iterator<Map.Entry<Integer, Room>> rooms = getRoomsIterator();
         while (rooms.hasNext()) {
             Map.Entry<Integer, Room> next = rooms.next();
             if (next.getValue().getItemIds().contains(itemId)) {
diff --git a/src/main/java/com/comandante/creeper/world/WorldExporter.java b/src/main/java/com/comandante/creeper/world/WorldExporter.java
index f7705289ff00b97e8a81fd9eab708b3d39f955c9..3859448085988222721b60181e4445cd851e37da 100644
--- a/src/main/java/com/comandante/creeper/world/WorldExporter.java
+++ b/src/main/java/com/comandante/creeper/world/WorldExporter.java
@@ -3,9 +3,6 @@ package com.comandante.creeper.world;
 import com.comandante.creeper.entity.EntityManager;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.managers.SentryManager;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterators;
 import com.google.common.collect.Sets;
 import com.google.common.io.Files;
 import com.google.gson.GsonBuilder;
@@ -15,6 +12,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.charset.Charset;
 import java.util.*;
+import java.util.function.Function;
 
 public class WorldExporter {
 
@@ -59,78 +57,67 @@ public class WorldExporter {
         floorModel.setRawMatrixCsv(mapMatrix.getCsv());
         floorModel.setRoomModels((new HashSet<RoomModel>()));
         floorModel.setName(floorManager.getName(floorId));
-        Iterator<RoomModel> roomModels = Iterators.transform(rooms.iterator(), buildRoomModelsFromRooms());
-        while (roomModels.hasNext()) {
-            RoomModel next = roomModels.next();
-            floorModel.getRoomModels().add(next);
-        }
+        rooms.stream()
+                .map(buildRoomModelsFromRooms())
+                .forEach(roomModel -> floorModel.getRoomModels()
+                        .add(roomModel));
         return floorModel;
     }
 
     public static Function<Room, RoomModel> buildRoomModelsFromRooms() {
-        return new Function<Room, RoomModel>() {
-            @Override
-            public RoomModel apply(Room room) {
-                RoomModelBuilder roomModelBuilder = new RoomModelBuilder();
-                for (RemoteExit remoteExit : room.getEnterExits()) {
-                    roomModelBuilder.addEnterExitName(remoteExit.getRoomId(), remoteExit.getExitDetail());
-                }
-                roomModelBuilder.setRoomDescription(room.getRoomDescription());
-                roomModelBuilder.setRoomTitle(room.getRoomTitle());
-                roomModelBuilder.setRoomId(room.getRoomId());
-                roomModelBuilder.setRoomTags(room.getRoomTags());
-                roomModelBuilder.setFloorId(room.getFloorId());
-                for (Area area : room.getAreas()) {
-                    roomModelBuilder.addAreaName(area.getName());
-                }
-                for (Map.Entry<String, String> notable : room.getNotables().entrySet()) {
-                    roomModelBuilder.addNotable(notable.getKey(), notable.getValue());
-                }
-                return roomModelBuilder.build();
+        return room -> {
+            RoomModelBuilder roomModelBuilder = new RoomModelBuilder();
+            for (RemoteExit remoteExit : room.getEnterExits()) {
+                roomModelBuilder.addEnterExitName(remoteExit.getRoomId(), remoteExit.getExitDetail());
             }
+            roomModelBuilder.setRoomDescription(room.getRoomDescription());
+            roomModelBuilder.setRoomTitle(room.getRoomTitle());
+            roomModelBuilder.setRoomId(room.getRoomId());
+            roomModelBuilder.setRoomTags(room.getRoomTags());
+            roomModelBuilder.setFloorId(room.getFloorId());
+            for (Area area : room.getAreas()) {
+                roomModelBuilder.addAreaName(area.getName());
+            }
+            for (Map.Entry<String, String> notable : room.getNotables().entrySet()) {
+                roomModelBuilder.addNotable(notable.getKey(), notable.getValue());
+            }
+            return roomModelBuilder.build();
         };
     }
 
     public Function<RoomModel, BasicRoom> getBasicRoom(final MapMatrix mapMatrix) {
-        return new Function<RoomModel, BasicRoom>() {
-            @Override
-            public BasicRoom apply(RoomModel roomModel) {
-                BasicRoomBuilder basicRoomBuilder = new BasicRoomBuilder(gameManager)
-                        .setRoomId(roomModel.getRoomId())
-                        .setFloorId(roomModel.getFloorId())
-                        .setRoomDescription(roomModel.getRoomDescription())
-                        .setRoomTitle(roomModel.getRoomTitle());
-
-                for (String tag : roomModel.getRoomTags()) {
-                    basicRoomBuilder.addTag(tag);
-                }
-                for (String areaName : roomModel.getAreaNames()) {
-                    Area byName = Area.getByName(areaName);
-                    if (byName != null) {
-                        basicRoomBuilder.addArea(byName);
-                    }
+        return roomModel -> {
+            BasicRoomBuilder basicRoomBuilder = new BasicRoomBuilder(gameManager)
+                    .setRoomId(roomModel.getRoomId())
+                    .setFloorId(roomModel.getFloorId())
+                    .setRoomDescription(roomModel.getRoomDescription())
+                    .setRoomTitle(roomModel.getRoomTitle());
+
+            for (String tag : roomModel.getRoomTags()) {
+                basicRoomBuilder.addTag(tag);
+            }
+            for (String areaName : roomModel.getAreaNames()) {
+                Area byName = Area.getByName(areaName);
+                if (byName != null) {
+                    basicRoomBuilder.addArea(byName);
                 }
-                Map<String, String> enterExitNames = roomModel.getEnterExitNames();
-                if (enterExitNames != null) {
-                    Iterator<Map.Entry<String, String>> iterator = enterExitNames.entrySet().iterator();
-                    while (iterator.hasNext()) {
-                        Map.Entry<String, String> next = iterator.next();
-                        RemoteExit remoteExit = new RemoteExit(RemoteExit.Direction.ENTER, Integer.parseInt(next.getKey()), next.getValue());
-                        basicRoomBuilder.addEnterExit(remoteExit);
-                        mapMatrix.addRemote(roomModel.getRoomId(), remoteExit);
-                    }
+            }
+            Map<String, String> enterExitNames = roomModel.getEnterExitNames();
+            if (enterExitNames != null) {
+                for (Map.Entry<String, String> next : enterExitNames.entrySet()) {
+                    RemoteExit remoteExit = new RemoteExit(RemoteExit.Direction.ENTER, Integer.parseInt(next.getKey()), next.getValue());
+                    basicRoomBuilder.addEnterExit(remoteExit);
+                    mapMatrix.addRemote(roomModel.getRoomId(), remoteExit);
                 }
-                Map<String, String> notables = roomModel.getNotables();
-                if (notables != null) {
-                    Iterator<Map.Entry<String, String>> iterator = notables.entrySet().iterator();
-                    while (iterator.hasNext()) {
-                        Map.Entry<String, String> next = iterator.next();
-                        basicRoomBuilder.addNotable(next.getKey(), next.getValue());
-                    }
+            }
+            Map<String, String> notables = roomModel.getNotables();
+            if (notables != null) {
+                for (Map.Entry<String, String> next : notables.entrySet()) {
+                    basicRoomBuilder.addNotable(next.getKey(), next.getValue());
                 }
-                configureExits(basicRoomBuilder, mapMatrix, roomModel.getRoomId());
-                return basicRoomBuilder.createBasicRoom();
             }
+            configureExits(basicRoomBuilder, mapMatrix, roomModel.getRoomId());
+            return basicRoomBuilder.createBasicRoom();
         };
     }
 
@@ -189,17 +176,26 @@ public class WorldExporter {
             mapsManager.addFloorMatrix(floorModel.getId(), matrixFromCsv);
             return;
         }
-        Iterator<BasicRoom> transform = Iterators.transform(floorModel.getRoomModels().iterator(), getBasicRoom(matrixFromCsv));
-        while (transform.hasNext()) {
-            BasicRoom next = transform.next();
-            entityManager.addEntity(next);
-        }
+        floorModel.getRoomModels().stream().map(getBasicRoom(matrixFromCsv)).forEach(entityManager::addEntity);
         floorManager.addFloor(floorModel.getId(), floorModel.getName());
         mapsManager.addFloorMatrix(floorModel.getId(), matrixFromCsv);
     }
 
     public void readWorldFromDisk() throws FileNotFoundException {
         WorldModel worldModel = new GsonBuilder().create().fromJson(Files.newReader(new File(("world/world.json")), Charset.defaultCharset()), WorldModel.class);
+        worldModel.getFloorModelList()
+                .forEach(this::buildFloor);
+    }
+
+    public void buildTestworld() {
+        WorldModel worldModel = new GsonBuilder().create().fromJson("{\n" +
+                "  \"floorModelList\": [\n" +
+                "    {\n" +
+                "      \"name\": \"main\",\n" +
+                "      \"id\": 0,\n" +
+                "      \"rawMatrixCsv\": \"0,1\"\n" +
+                "}]\n" +
+                "}", WorldModel.class);
         for (FloorModel next : worldModel.getFloorModelList()) {
             buildFloor(next);
         }
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
old mode 100755
new mode 100644
diff --git a/src/test/com/comandante/creeper/CreeperUtilsTest.java b/src/test/com/comandante/creeper/CreeperUtilsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b91ef6e991eae7816708a671ee4f3f0d8813e57
--- /dev/null
+++ b/src/test/com/comandante/creeper/CreeperUtilsTest.java
@@ -0,0 +1,47 @@
+package com.comandante.creeper;
+
+import com.comandante.creeper.Items.ItemType;
+import com.comandante.creeper.entity.EntityManager;
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.player.*;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.junit.Test;
+import org.mockito.Matchers;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CreeperUtilsTest {
+
+    @Test
+    public void testCombineStrings() throws Exception {
+        String[] strings = new String[2];
+        strings[0] = "feet";
+        strings[1] = "hand";
+        PlayerMetadata playerMetadata = new PlayerMetadata("usertest", "Testtest", Main.createPlayerId("usertest"), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), strings, 0, new String[0], Maps.newHashMap());
+        GameManager gameManager = mock(GameManager.class);
+        StatsModifierFactory statsModifierFactory = mock(StatsModifierFactory.class);
+        when(statsModifierFactory.getStatsModifier(Matchers.any())).thenReturn(PlayerStats.DEFAULT_PLAYER.createStats());
+        when(gameManager.getStatsModifierFactory()).thenReturn(statsModifierFactory);
+        PlayerManager playerManager = mock(PlayerManager.class);
+        when(playerManager.getPlayerMetadata(Matchers.any())).thenReturn(playerMetadata);
+        when(gameManager.getPlayerManager()).thenReturn(playerManager);
+        EntityManager entityManager = mock(EntityManager.class);
+        when(entityManager.getItemEntity(Matchers.startsWith("feet"))).thenReturn(ItemType.BERSEKER_BOOTS.create());
+        when(entityManager.getItemEntity(Matchers.startsWith("hand"))).thenReturn(ItemType.BERSERKER_BATON.create());
+        when(gameManager.getEntityManager()).thenReturn(entityManager);
+        Player usertest = new Player("usertest", gameManager);
+
+        String s = CreeperUtils.printStringsNextToEachOther(Lists.newArrayList(usertest.getLookString(), usertest.getLookString()), "");
+
+        System.out.println(s);
+
+
+        System.out.println(usertest.getLookString().replaceAll("\u001B\\[[;\\d]*m", ""));
+
+
+    }
+
+}
\ No newline at end of file
diff --git a/src/test/com/comandante/creeper/player/ExperienceManagerTest.java b/src/test/com/comandante/creeper/player/ExperienceManagerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e97784c345acaee7104d4ebb7b6db35a2c375b11
--- /dev/null
+++ b/src/test/com/comandante/creeper/player/ExperienceManagerTest.java
@@ -0,0 +1,44 @@
+package com.comandante.creeper.player;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+
+public class ExperienceManagerTest {
+
+    private ExperienceManager experienceManager;
+
+    @Before
+    public void setUp() throws Exception {
+        experienceManager = new ExperienceManager();
+    }
+
+    @Test
+    public void testXp() throws Exception {
+        int playerLevel = 20;
+        Assert.assertEquals(0, experienceManager.calculateNpcXp(playerLevel, 13));
+        Assert.assertEquals(0, experienceManager.calculateNpcXp(playerLevel, 12));
+        Assert.assertEquals(232, experienceManager.calculateNpcXp(playerLevel, 23));
+        Assert.assertEquals(203, experienceManager.calculateNpcXp(playerLevel, 22));
+        Assert.assertEquals(174, experienceManager.calculateNpcXp(playerLevel, 21));
+        Assert.assertEquals(145, experienceManager.calculateNpcXp(playerLevel, 20));
+        Assert.assertEquals(132, experienceManager.calculateNpcXp(playerLevel, 19));
+        Assert.assertEquals(119, experienceManager.calculateNpcXp(playerLevel, 18));
+        int npcLevel = 3;
+        for (int i = 0; i < 10; i++) {
+            System.out.println("Player Level: " + i + " xp gained: " + experienceManager.calculateNpcXp(i, npcLevel));
+        }
+    }
+
+
+    @Test
+    public void testSpread() throws Exception {
+        //System.out.println("Player Level: " + 28 + " " + experienceManager.getLevelColor(28, 25) + " " + experienceManager.calculateNpcXp(28, 25));
+//        System.out.println("Player Level: " + 29 + " " + experienceManager.getLevelColor(29, 25) + " " + experienceManager.calculateNpcXp(29, 25));
+
+        for (int i = 15; i < 30; i++) {
+            System.out.println("Player Level: " + i + " " + experienceManager.getLevelColor(i, 25) + " " + experienceManager.calculateNpcXp(i, 25));
+      }
+    }
+}
\ No newline at end of file
diff --git a/src/test/com/comandante/creeper/player/LevelsTest.java b/src/test/com/comandante/creeper/player/LevelsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..dad461bc3c6d49157aace404fc3ae552c8967676
--- /dev/null
+++ b/src/test/com/comandante/creeper/player/LevelsTest.java
@@ -0,0 +1,30 @@
+package com.comandante.creeper.player;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class LevelsTest {
+
+    @Test
+    public void testLevels() throws Exception {
+        for (int i = 0; i < 100; i++) {
+            long xp = Levels.getXp(i);
+            long level = Levels.getLevel(xp);
+            Assert.assertEquals(level, i);
+            System.out.println("Level: " + i + " | XP: " + xp);
+        }
+    }
+
+    @Test
+    public void printHowMuchXpIsNecessaryToLevelUp() throws Exception {
+        for (int i = 0; i < 100; i++) {
+            long xp = Levels.getXp(i);
+            long level = Levels.getLevel(xp);
+            long xpNext = Levels.getXp(i + 1);
+            long l = xpNext - xp;
+            System.out.println("Level " + i + " to " + (i + 1) + " takes " + l + " xp.");
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/com/comandante/creeper/player/NpcTestHarness.java b/src/test/com/comandante/creeper/player/NpcTestHarness.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebead4eec9ad2734961b9986efcd813e5cbd3da1
--- /dev/null
+++ b/src/test/com/comandante/creeper/player/NpcTestHarness.java
@@ -0,0 +1,230 @@
+package com.comandante.creeper.player;
+
+import com.comandante.creeper.ConfigureCommands;
+import com.comandante.creeper.CreeperConfiguration;
+import com.comandante.creeper.Items.Item;
+import com.comandante.creeper.Items.ItemType;
+import com.comandante.creeper.Main;
+import com.comandante.creeper.entity.EntityManager;
+import com.comandante.creeper.managers.GameManager;
+import com.comandante.creeper.managers.SessionManager;
+import com.comandante.creeper.npc.Npc;
+import com.comandante.creeper.npc.NpcBuilder;
+import com.comandante.creeper.npc.NpcExporter;
+import com.comandante.creeper.server.ChannelCommunicationUtils;
+import com.comandante.creeper.server.CreeperSession;
+import com.comandante.creeper.world.MapsManager;
+import com.comandante.creeper.world.RoomManager;
+import com.comandante.creeper.world.WorldExporter;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.commons.configuration.MapConfiguration;
+import org.jboss.netty.channel.Channel;
+import org.junit.Before;
+import org.junit.Test;
+import org.mapdb.DB;
+import org.mapdb.DBMaker;
+import org.nocrala.tools.texttablefmt.BorderStyle;
+import org.nocrala.tools.texttablefmt.ShownBorders;
+import org.nocrala.tools.texttablefmt.Table;
+
+import java.io.FileNotFoundException;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+import static org.mockito.Mockito.mock;
+
+public class NpcTestHarness {
+
+    private GameManager gameManager;
+    private EntityManager entityManager;
+    private int totalFightRounds = 0;
+
+    @Before
+    public void setUp() throws Exception {
+        ChannelCommunicationUtils channelUtils = new ChannelCommunicationUtils() {
+            @Override
+            public void write(String playerId, String message) {
+                //System.out.println(message);
+            }
+
+            @Override
+            public void write(String playerId, String message, boolean leadingBlankLine) {
+                // System.out.println(message);
+            }
+        };
+        CreeperConfiguration creeperConfiguration = new CreeperConfiguration(new MapConfiguration(Maps.newHashMap()));
+        DB db = DBMaker.newMemoryDB().closeOnJvmShutdown().make();
+        PlayerManager playerManager = new PlayerManager(db, new SessionManager());
+        RoomManager roomManager = new RoomManager(playerManager);
+        MapsManager mapsManager = new MapsManager(creeperConfiguration, roomManager);
+        EntityManager entityManager = new EntityManager(roomManager, playerManager, db);
+        GameManager gameManager = new GameManager(creeperConfiguration, roomManager, playerManager, entityManager, mapsManager, channelUtils);
+        WorldExporter worldExporter = new WorldExporter(roomManager, mapsManager, gameManager.getFloorManager(), entityManager, gameManager);
+        worldExporter.buildTestworld();
+        ConfigureCommands.configure(gameManager);
+        this.entityManager = entityManager;
+        this.gameManager = gameManager;
+    }
+
+    @Test
+    public void testAnotherCombat() throws Exception {
+        Set<Item> equipment = Sets.newHashSet();
+        equipment.add(ItemType.BERSEKER_BOOTS.create());
+        //equipment.add(ItemType.BERSERKER_BATON.create());
+        equipment.add(ItemType.BERSERKER_CHEST.create());
+        equipment.add(ItemType.BERSEKER_SHORTS.create());
+        String username = UUID.randomUUID().toString();
+        Player player = createRandomPlayer(username, 0);
+        equipArmor(player, equipment);
+        List<Npc> npcsFromFile = NpcExporter.getNpcsFromFile(gameManager);
+        Npc treeBerseker = npcsFromFile.stream().filter(npc -> npc.getName().equals("tree berserker")).collect(Collectors.toList()).get(0);
+        Npc npc = new NpcBuilder(treeBerseker).createNpc();
+        gameManager.getEntityManager().addEntity(npc);
+        player.getCurrentRoom().addPresentNpc(npc.getEntityId());
+        player.addActiveFight(npc);
+        conductFight(player, npc);
+    }
+
+    @Test
+    public void testCombat() throws Exception {
+        List<Npc> npcsFromFile = NpcExporter.getNpcsFromFile(gameManager);
+        Npc treeBerseker = npcsFromFile.stream().filter(npc -> npc.getName().equals("red-eyed bear")).collect(Collectors.toList()).get(0);
+        int totalIterations = 100;
+        Player player;
+        Npc npc = null;
+        Table t = new Table(8, BorderStyle.BLANKS,
+                ShownBorders.NONE);
+        t.setColumnWidth(0, 20, 20);
+        t.setColumnWidth(1, 15, 20);
+        t.setColumnWidth(2, 13, 16);
+        t.setColumnWidth(3, 10, 16);
+        t.setColumnWidth(4, 13, 16);
+        t.setColumnWidth(5, 10, 16);
+        t.setColumnWidth(6, 13, 16);
+        //t.setColumnWidth(6, 16, 16);
+
+        t.addCell("Npc");
+        t.addCell("Player Level");
+        t.addCell("Player Win");
+        t.addCell("Npc Win");
+        t.addCell("Avg Turns");
+        t.addCell("Avg Gold");
+        t.addCell("XP Earned");
+        t.addCell("Drops");
+        Set<Item> equipment = Sets.newHashSet();
+        equipment.add(ItemType.BERSEKER_BOOTS.create());
+        equipment.add(ItemType.BERSERKER_BATON.create());
+        equipment.add(ItemType.BERSERKER_CHEST.create());
+        equipment.add(ItemType.BERSEKER_SHORTS.create());
+        equipment.add(ItemType.BERSERKER_BRACERS.create());
+        equipment.add(ItemType.BERSEKER_HELM.create());
+
+        for (int level = 0; level < 10; level++) {
+            int playerWins = 0;
+            int npcWins = 0;
+            int totalGold = 0;
+            totalFightRounds = 0;
+            Map<String, AtomicInteger> drops = new HashMap<String, AtomicInteger>();
+            for (int i = 0; i < 100; i++) {
+                String username = UUID.randomUUID().toString();
+                player = createRandomPlayer(username, level);
+                equipArmor(player, equipment);
+                npc = new NpcBuilder(treeBerseker).createNpc();
+                npc.setCurrentRoom(player.getCurrentRoom());
+                gameManager.getEntityManager().addEntity(npc);
+                player.getCurrentRoom().addPresentNpc(npc.getEntityId());
+                player.addActiveFight(npc);
+                if (conductFight(player, npc)) {
+                    playerWins++;
+                    int gold = (int) gameManager.getLootManager().lootGoldAmountReturn(npc.getLoot());
+                    totalGold += gold;
+                    Set<Item> items = gameManager.getLootManager().lootItemsReturn(npc.getLoot());
+                    items.forEach(item -> {
+                        if (!drops.containsKey(item.getItemName())) {
+                            drops.put(item.getItemName(), new AtomicInteger(1));
+                        } else {
+                            drops.get(item.getItemName()).incrementAndGet();
+                        }
+                    });
+                } else {
+                    npcWins++;
+                }
+                player.getCurrentRoom().removePresentNpc(npc.getEntityId());
+                entityManager.deleteNpcEntity(npc.getEntityId());
+                player.getCurrentRoom().removePresentPlayer(player.getPlayerId());
+            }
+            float playerWinPercent = (playerWins * 100.0f) / totalIterations;
+            float npcWinPercent = (npcWins * 100.0f) / totalIterations;
+            t.addCell(npc.getName());
+            t.addCell(String.valueOf(level));
+            t.addCell(String.valueOf(playerWinPercent) + "%");
+            t.addCell(String.valueOf(npcWinPercent) + "%");
+            t.addCell(String.valueOf(totalFightRounds / totalIterations));
+            if (totalGold == 0 || playerWins == 0) {
+                t.addCell("0");
+            } else {
+                t.addCell(String.valueOf(totalGold / playerWins));
+            }
+            t.addCell(String.valueOf(new ExperienceManager().calculateNpcXp(level, (int) Levels.getLevel(npc.getStats().getExperience()))));
+            StringBuilder sb = new StringBuilder();
+            drops.entrySet().stream().map(entry -> entry.getKey() + "(" + entry.getValue().get() + ")").forEach(s -> sb.append(s).append(","));
+            t.addCell(sb.toString());
+        }
+        System.out.println("#### 100 round fight simulation results ####");
+        System.out.println(t.render());
+
+        // Stats difference = StatsHelper.getDifference(player.getPlayerStatsWithEquipmentAndLevel(), new PlayerStats().DEFAULT_PLAYER.createStats());
+        // String player1 = gameManager.buildLookString("player", player.getPlayerStatsWithEquipmentAndLevel(),difference );
+        // System.out.println(player1);
+        // System.out.println("");
+
+    }
+
+    private boolean conductFight(Player player, Npc npc) {
+        int i = 0;
+        try {
+            for (i = 0; i < 1000; i++) {
+                player.run();
+                npc.run();
+                if (!npc.getIsAlive().get()) {
+                    return true;
+                }
+                if (player.isActive(CoolDownType.DEATH)) {
+                    return false;
+                }
+            }
+            return false;
+        } finally {
+            totalFightRounds += i;
+        }
+    }
+
+    private Player createRandomPlayer(String username, int level) throws FileNotFoundException {
+        createUser(username, "3333333");
+        Player player = new Player(username, gameManager);
+        Channel mockChannel = mock(Channel.class);
+        CreeperSession creeperSession = new CreeperSession();
+        creeperSession.setUsername(Optional.of(username));
+        player.setChannel(mockChannel);
+        gameManager.getPlayerManager().addPlayer(player);
+        gameManager.placePlayerInLobby(player);
+        gameManager.getPlayerManager().getSessionManager().putSession(creeperSession);
+        player.addExperience(Levels.getXp(level));
+        return player;
+    }
+
+    private void equipArmor(Player player, Set<Item> equipment) {
+        equipment.forEach(item -> {
+            entityManager.saveItem(item);
+            gameManager.acquireItem(player, item.getItemId());
+            player.equip(item);
+        });
+    }
+
+    private void createUser(String username, String password) {
+        PlayerMetadata playerMetadata = new PlayerMetadata(username, password, Main.createPlayerId(username), PlayerStats.DEFAULT_PLAYER.createStats(), 0, Sets.newHashSet(PlayerRole.MORTAL), new String[0], 0, new String[0], Maps.newHashMap());
+        gameManager.getPlayerManager().savePlayerMetadata(playerMetadata);
+    }
+}
diff --git a/src/test/com/comandante/creeper/server/GossipCacheTest.java b/src/test/com/comandante/creeper/server/GossipCacheTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..56710ea87146f1b4f1378427f4832c854182e7df
--- /dev/null
+++ b/src/test/com/comandante/creeper/server/GossipCacheTest.java
@@ -0,0 +1,38 @@
+package com.comandante.creeper.server;
+
+import com.comandante.creeper.CreeperConfiguration;
+import com.comandante.creeper.managers.GameManager;
+import com.google.api.client.util.Maps;
+import org.apache.commons.configuration.MapConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class GossipCacheTest {
+
+    GossipCache gossipCache;
+
+    @Before
+    public void setUp() throws Exception {
+        GameManager mock = mock(GameManager.class);
+        HashMap<String, Object> configuration = Maps.newHashMap();
+        configuration.put("max.gossip.cache.size", 100);
+        CreeperConfiguration creeperConfiguration = new CreeperConfiguration(new MapConfiguration(configuration));
+        when(mock.getCreeperConfiguration()).thenReturn(creeperConfiguration);
+        this.gossipCache = new GossipCache(mock);
+    }
+
+    @Test
+    public void testRecentGossip() throws Exception {
+        for (int i = 0; i < 20; i++) {
+            gossipCache.addGossipLine(String.valueOf(i));
+        }
+        List<String> recent = gossipCache.getRecent(20);
+    }
+
+}
\ No newline at end of file
diff --git a/world/6May2015-7PM b/world/6May2015-7PM
deleted file mode 100644
index 5674aa65a61052bd1391490075ef1c3fa43b6757..0000000000000000000000000000000000000000
--- a/world/6May2015-7PM
+++ /dev/null
@@ -1,4261 +0,0 @@
-{
-  "floorModelList": [
-    {
-      "name": "6339ed62-e0ec-41ab-9b67-31685a4cb0f3",
-      "id": 13,
-      "rawMatrixCsv": "69d|70,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 69,
-          "floorId": 13,
-          "roomDescription": "A large crest featuring the seal of the House of Firth can be seen decorating the polished marble floor of the foyer. Two staircases can be seen leading to the upper floor on opposite sides of the room, connected by a balcony. Behind one of the staircases, a set of stairs leads downward to the House locker room. To the east, a wood paneled seating area can be seen, with several tables and upholstered chairs.",
-          "roomTitle": "HOUSE OF FIRTH (Foyer)",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "42": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "31146a6b-8e5c-4113-841c-c4d486de4556",
-      "id": 4,
-      "rawMatrixCsv": "20u|2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 20,
-          "floorId": 4,
-          "roomDescription": "Underneath the Blacksmith shop, the walls are lined with swords, axes, shields, body armor, pikes, wagon parts and other inventory awaiting sale. A simple hand operated goods elevator can be seen in the corner, operated by rope and pulley and a large set of wooden gears, used to help carry inventory upstairs.",
-          "roomTitle": "BLACKSMITH STORE ROOM",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "6362a7a0-5931-4be5-9edd-7ca283d43821",
-      "id": 34,
-      "rawMatrixCsv": ",341,,,,,,\n,339,340,,,,,\n345,342u|343,344,,,,,\n,,346,349,,,,\n,,347,348d|350,351,,,\n,,,352,,,,\n,,354,353,355,,,\n,,358,356,357,,,\n,,359,360,361,,,\n",
-      "roomModels": [
-        {
-          "roomId": 361,
-          "floorId": 34,
-          "roomDescription": "These staff quarters house the majority of the house staff. Though somewhat cramped, they provide sufficient space for those working in the house, offering far better conditions of living than many of the peasant class employees might otherwise experience.",
-          "roomTitle": "MANOR HOUSE STAFF QUARTERS",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 341,
-          "floorId": 34,
-          "roomDescription": "Swords, shields, battle-axes, pikes, bows, and every other form of weapon imaginable hang from the walls here, ready to be used on short notice should the Manor House come under attack. Several large banners bearing the shield of the Manor can also be seen, hanging from the top of large poles which are used both in battle and on ceremonial occasions. A larger than life size painting, well over two hundred years old, depicts a soldier of the manor, clad in armor and holding a broadsword. Small windows allow light to enter the room from the west, built into the thick outer walls of the Manor House compound. These windows provide an excellent vantage point for archers to defend the Manor House. A stairway leads upward to one of the two main guard towers, built on the northern and southern ends of the complex.",
-          "roomTitle": "MANOR HOUSE ARMORY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 352,
-          "floorId": 34,
-          "roomDescription": "This short hallway leads south toward a wing mainly occupied by house staff, and toward the barracks of the Manor House. To the north is the Manor House kitchen.",
-          "roomTitle": "MANOR HOUSE (Hallway)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 354,
-          "floorId": 34,
-          "roomDescription": "With views toward the west through two small windows, partially obscured by the Manor House wall, the head butler of the house lives comfortably in this room. The room provides easy access to the kitchen, where the butler must often pick up food to bring to the dining area, and offers substantially more space than any of the other staff quarters.",
-          "roomTitle": "MANOR HOUSE (Butler\u0027s Quarters)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 345,
-          "floorId": 34,
-          "roomDescription": "This small space directly sitting against the western wall of the Manor House features small windows similar to those seen in the armory, and provides just enough room for archers to defend the complex by attacking enemies through the windows. A rack built on the wall holds an assortment of bows, and thousands of arrows can be seen in wooden crates throughout the room.",
-          "roomTitle": "MANOR HOUSE WEST WALL INTERIOR",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 340,
-          "floorId": 34,
-          "roomDescription": "The ceiling in this massive space is lined with stalactites, and the sound of dripping water can be heard echoing through the grotto. A small pool can be seen in the southeastern corner of the room, lined with precisely cut stones, and mosaic tiles surrounding the edges on top. A fire pit can be seen near the pool, used to heat large stones which are then placed in the pool to raise its otherwise cold temperature. Torch holders sit ten feet apart along all the walls, adding light to the otherwise dark space. A massive wooden table sitting on stone legs sits on the northern side of the room, mainly used as a dining table on very hot days.",
-          "roomTitle": "MANOR HOUSE GROTTO",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 355,
-          "floorId": 34,
-          "roomDescription": "This large room provides a privileged and comfortable living space for the head chef of the house. Though lacking windows, the room has a large number of candles which provide light, and is always warm due to the constantly operating kitchen nearby. The thick wooden door and stone walls provide for peace and quiet after grueling days of kitchen work.",
-          "roomTitle": "MANOR HOUSE (Chef\u0027s Quarters)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 359,
-          "floorId": 34,
-          "roomDescription": "These staff quarters house the majority of the house staff. Though somewhat cramped, they provide sufficient space for those working in the house, offering far better conditions of living than many of the peasant class employees might otherwise experience.",
-          "roomTitle": "MANOR HOUSE STAFF QUARTERS",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 344,
-          "floorId": 34,
-          "roomDescription": "This room is used to showcase the finest possessions of the House, acquired over centuries both through battle and through trade. Several ancient Roman stone busts rest on columns along one wall, and another wall features tapestries, including a centrally placed Persian tapestry, which features an ornate \"tree of life\" in its design. A massive hawk sculpture from Ancient Egypt, carved from lapis lazuli, sits on a stone pedestal at the center of the room, surrounded by an iron barrier to protect it from damage. A full set of knight\u0027s armor stands upright in a corner, once worn by the founder of the Manor, and a set of decorative chain mail armor is on display next to it, made of pure gold links.",
-          "roomTitle": "MANOR HOUSE GALLERY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 360,
-          "floorId": 34,
-          "roomDescription": "This simple lounge area features several tables, with wooden chairs, and a small fireplace, used exclusively by the house staff. The staff often share meals here and spend any leisure time they may have in this room. Windows facing south provide a view of some of the southern lands, and the Bloodridge Mountain ridge which curves to the east in the distance.",
-          "roomTitle": "MANOR HOUSE STAFF LOUNGE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 348,
-          "floorId": 34,
-          "roomDescription": "Two massive fireplaces dominate this room, with piles of wood stacked to their sides. Several iron ovens can also be seen in the room, which are either fueled with coals from the fireplaces, or more firewood. Using the fireplaces and ovens, the chefs of the Manor House are capable of baking, boiling, smoking, or roasting any type of food. Cast iron cooking implements hang from racks on both the walls and the ceiling. A rack carries a set of exquisite cooking knives, forged and shaped painstakingly by the town blacksmith.",
-          "roomTitle": "MANOR HOUSE KITCHEN",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 346,
-          "floorId": 34,
-          "roomDescription": "Used for the most formal dinners in the house, this dining room features a thick oak table inlaid at its edges with emeralds and other precious stones. Two fireplaces heat this large room in colder months, and matters of governing and administrating the town are often discussed over meals here, as well as meetings with other rulers who have traveled here for discussions and negotiation. The wooden chairs surrounding the table each have upholstered cushions, evenly stuffed by hand with horsehair. Silver candle holders can be found every few feet down the table, each holding two candles and sculpted in the form of a sitting lion.",
-          "roomTitle": "MANOR HOUSE DINING ROOM",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 358,
-          "floorId": 34,
-          "roomDescription": "A long room extending from east to west is lined with bunks for soldiers and equipment. While normally not very crowded, it provides enough space for soldiers in the event of a siege on the town. The simple wooden bunks are uncushioned, but sufficient.",
-          "roomTitle": "MANOR HOUSE BARRACKS",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 357,
-          "floorId": 34,
-          "roomDescription": "A long room extending from east to west is lined with bunks for soldiers and equipment. While normally not very crowded, it provides enough space for soldiers in the event of a siege on the town. The simple wooden bunks are uncushioned, but sufficient.",
-          "roomTitle": "MANOR HOUSE BARRACKS",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 342,
-          "floorId": 34,
-          "roomDescription": "Though a smaller space than the grotto, this is the largest finished room in the Manor House, and from here archways and doorways lead to the main living spaces of the complex. A stone staircase sits at the center of the room to the south, leading to a balcony that surrounds the eastern, western and southern sides of the second level of the building. The ceiling of the room can be seen two stories above, decorated with frescos featuring the flatlands to the west, and the Bloodridge Mountains to the east. A chandelier made from deer antlers hangs from the center, capable of holding a large number of candles which are lit using a long pole, a task requiring two people given how heavy and unwieldy it is.",
-          "roomTitle": "MANOR HOUSE MAIN HALL",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 351,
-          "floorId": 34,
-          "roomDescription": "This large pantry mainly stores the non perishable food needed by the house kitchen. Sitting just behind and near one of the main fireplaces, this room is kept dry and warm most of the time. The walls are paneled with wood, and food items are stacked all around the room on simple wooden shelves.",
-          "roomTitle": "MANOR HOUSE PANTRY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 349,
-          "floorId": 34,
-          "roomDescription": "This small parlor provides space for dinner guests to enjoy refreshments prior to dinner service commencing. Couches with horsehair cushions can be found throughout the room, as well as a cabinet well stocked with various liquors, and a heavy trunk regularly stocked with freshly brewed beers brought from the cellar. A table toward the corner of the room has a chess board integrated into it, with squares made of slate and obsidian.",
-          "roomTitle": "MANOR HOUSE PARLOR",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 353,
-          "floorId": 34,
-          "roomDescription": "From this central point in the south wing of the Manor House, doorways lead to staff quarters and to the barracks.",
-          "roomTitle": "MANOR HOUSE (South Wing)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 356,
-          "floorId": 34,
-          "roomDescription": "A long room extending from east to west is lined with bunks for soldiers and equipment. While normally not very crowded, it provides enough space for soldiers in the event of a siege on the town. The simple wooden bunks are uncushioned, but sufficient.",
-          "roomTitle": "MANOR HOUSE BARRACKS",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 339,
-          "floorId": 34,
-          "roomDescription": "The expansive courtyard surrounds a marble fountain crowned by four carved lion heads. The courtyard is paved with red bricks, providing the largest space within the Manor House compound for large gatherings. A colonnade provides a covered walkway around all four sides of the courtyard, supported by sandstone columns. A hawthorn tree stands at the northeast corner of the courtyard, covering it in shade. An arched doorway to the east leads to a stone grotto, carved into the Bloodridge Mountains over millions of years by the melting glaciers high above. Two further arches lead to the inside of the Manor House both to the north and to the south. To the west, the iron gate leads back to town.",
-          "roomTitle": "MANOR HOUSE COURTYARD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "33": "Leave"
-          }
-        },
-        {
-          "roomId": 347,
-          "floorId": 34,
-          "roomDescription": "This terrace sits under part of the second floor of the manor house, and so is covered by a roof with large wooden beams visible, providing structural support to the second floor. The terrace sits several steps above the main dining room, and so offers a far ranging view to the south and to the west, over the Manor House walls. Several stone benches and wooden chairs can be found scattered around the terrace. Vines from hanging plants drape down from their pots near the terrace roof, spaced widely enough to not obscure the view.",
-          "roomTitle": "MANOR HOUSE DINING ROOM TERRACE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "eb4a325b-032f-4771-b9fc-b20e61a93c41",
-      "id": 23,
-      "rawMatrixCsv": "300,296,295,292,293,294,,,,,,,,,,,\n298,297,288,291,,,,,,,,,,,,,\n299,290,287,289,,,,,,,,,,,,,\n,,286,,,,,,,,,,,,,,\n,,285,284,,,,,,,,,,,,,\n,,,283,,,,,,,,,,,,,\n,,,282,,,,,,,,,,,,,\n,251,245,250,,,,,,,,,,,,,\n,,244,249,,,,,,,,,,,,,\n,252,243,242,241,,,,,,,,,,,,\n,,246,248,,,,,,,,,,,,,\n,,247,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 243,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 285,
-          "floorId": 23,
-          "roomDescription": "The Charcoal Forest once was considered part of the Royal Hunting Grounds, but a series of wildfires in the past did irreparable damage to the landscape, and the blackened, charred remains of trees can still be seen. Incredibly, this appears to be the ideal habitat for several creatures, which quickly moved in as others moved out. The creatures here are known for their particular hostility, and many believe they themselves were responsible for burning down the forest.",
-          "roomTitle": "CHARCOAL FOREST PATH",
-          "roomTags": [],
-          "areaNames": [
-            "north7_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 251,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 244,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 295,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 247,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 249,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 288,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 245,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 299,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 242,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 284,
-          "floorId": 23,
-          "roomDescription": "The Charcoal Forest once was considered part of the Royal Hunting Grounds, but a series of wildfires in the past did irreparable damage to the landscape, and the blackened, charred remains of trees can still be seen. Incredibly, this appears to be the ideal habitat for several creatures, which quickly moved in as others moved out. The creatures here are known for their particular hostility, and many believe they themselves were responsible for burning down the forest.",
-          "roomTitle": "CHARCOAL FOREST PATH",
-          "roomTags": [],
-          "areaNames": [
-            "north7_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 297,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 293,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 250,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat. To the north, a path leading to the Charcoal Forest can be seen.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 282,
-          "floorId": 23,
-          "roomDescription": "The Charcoal Forest once was considered part of the Royal Hunting Grounds, but a series of wildfires in the past did irreparable damage to the landscape, and the blackened, charred remains of trees can still be seen. Incredibly, this appears to be the ideal habitat for several creatures, which quickly moved in as others moved out. The creatures here are known for their particular hostility, and many believe they themselves were responsible for burning down the forest.",
-          "roomTitle": "CHARCOAL FOREST PATH",
-          "roomTags": [],
-          "areaNames": [
-            "north7_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 292,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 252,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 248,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 290,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 294,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 287,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 241,
-          "floorId": 23,
-          "roomDescription": "A small gate on the western side of the Town of Hammoor leads to the former Royal Hunting Grounds. A stone barbican guards the entrance to the city here, though it is much smaller than the one guarding the main entrance.",
-          "roomTitle": "TOWN OF HAMMOOR (West Gate)",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {
-            "240": "Leave"
-          }
-        },
-        {
-          "roomId": 246,
-          "floorId": 23,
-          "roomDescription": "Though the town of Hammoor has not been ruled by a monarch for many years, these grounds to the west of the town were initially set aside as royal hunting property. With slightly thinned out vegetation, a large population of creatures has settled here, including a number of species of wildcat.",
-          "roomTitle": "HAMMOOR ROYAL HUNTING GROUNDS",
-          "roomTags": [],
-          "areaNames": [
-            "north5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 289,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 300,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 286,
-          "floorId": 23,
-          "roomDescription": "The Charcoal Forest once was considered part of the Royal Hunting Grounds, but a series of wildfires in the past did irreparable damage to the landscape, and the blackened, charred remains of trees can still be seen. Incredibly, this appears to be the ideal habitat for several creatures, which quickly moved in as others moved out. The creatures here are known for their particular hostility, and many believe they themselves were responsible for burning down the forest.",
-          "roomTitle": "CHARCOAL FOREST PATH",
-          "roomTags": [],
-          "areaNames": [
-            "north7_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 291,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 298,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 283,
-          "floorId": 23,
-          "roomDescription": "The Charcoal Forest once was considered part of the Royal Hunting Grounds, but a series of wildfires in the past did irreparable damage to the landscape, and the blackened, charred remains of trees can still be seen. Incredibly, this appears to be the ideal habitat for several creatures, which quickly moved in as others moved out. The creatures here are known for their particular hostility, and many believe they themselves were responsible for burning down the forest.",
-          "roomTitle": "CHARCOAL FOREST PATH",
-          "roomTags": [],
-          "areaNames": [
-            "north7_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 296,
-          "floorId": 23,
-          "roomDescription": "Here, in the heart of the Charcoal Forest, an apocalyptic landscape surrounds you, and charcoal dust is picked up into the air whenever a gust of wind blows through the area. Though low lying plants such as ferns appear to be thriving, with very little forest vegetation left to shield them from the sun, the majority of the larger trees have been reduced to blackened stumps.",
-          "roomTitle": "CHARCOAL FOREST",
-          "roomTags": [],
-          "areaNames": [
-            "north8_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "53d31ac2-9e42-4bc2-849f-ea11d4a1f59b",
-      "id": 26,
-      "rawMatrixCsv": "256,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 256,
-          "floorId": 26,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "237": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "8da278ed-4206-48bf-9809-879cf44ae5ac",
-      "id": 10,
-      "rawMatrixCsv": "65,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 65,
-          "floorId": 10,
-          "roomDescription": "A large domed ceiling encloses the Town Bank, with rows of decorative columns lining two sides. The town banker can be seen at the end of the room behind a large desk, and a large vault sits behind the banker.",
-          "roomTitle": "TOWN BANK",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "24": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "1e235e77-6d38-4155-b5e7-52bad9c121e5",
-      "id": 19,
-      "rawMatrixCsv": ",,313,314,315,316,,,,,,,,,,,,,,,\n,,312,,,317,318,319,,,,,,,,,,,,,\n,,304,305,306,307,,320,,,,,,,,,,,,,\n,,303,,,308,322,321,,,,,,,,,,,,,\n146,301,302,311,310,309,,327,,,,,,,,,,,,,\n,,,,324,323,325,326,,,,,,,,,,,,,\n,,,,,332,,328,,,,,,,,,,,,,\n,,,,,331,330,329,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 321,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 323,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 327,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 314,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE (Warebeth Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 325,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 306,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 312,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE (Munro Place)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 320,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 330,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 328,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 313,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE (Warebeth Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 305,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 318,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 319,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 326,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 332,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 322,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 304,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE (Munro Place)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 316,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 303,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE (Munro Place)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 317,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 309,
-          "floorId": 19,
-          "roomDescription": "Evidence of the former splendor of Segeberg Castle is seen on this wide road, iterated by small dirt patches on the sides, some of which still hold trees. The ruins of buildings run along both sides of the road, elegant architectural details visible decorating crumbling stone structures. Weeds grow through the cracks in the cobblestone, as nature slowly reclaims the castle town.",
-          "roomTitle": "SEGEBERG CASTLE (Segeberg Parade)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 311,
-          "floorId": 19,
-          "roomDescription": "Evidence of the former splendor of Segeberg Castle is seen on this wide road, iterated by small dirt patches on the sides, some of which still hold trees. The ruins of buildings run along both sides of the road, elegant architectural details visible decorating crumbling stone structures. Weeds grow through the cracks in the cobblestone, as nature slowly reclaims the castle town.",
-          "roomTitle": "SEGEBERG CASTLE (Segeberg Parade)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 307,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 331,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 310,
-          "floorId": 19,
-          "roomDescription": "Evidence of the former splendor of Segeberg Castle is seen on this wide road, iterated by small dirt patches on the sides, some of which still hold trees. The ruins of buildings run along both sides of the road, elegant architectural details visible decorating crumbling stone structures. Weeds grow through the cracks in the cobblestone, as nature slowly reclaims the castle town.",
-          "roomTitle": "SEGEBERG CASTLE (Segeberg Parade)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 308,
-          "floorId": 19,
-          "roomDescription": "Formerly a vibrant marketplace, Merchants Lane today has been reduced to rubble. The structures lining this throughway seem to be decaying more rapidly than most of the town, as most of the shops were cheaply constructed by cost sensitive tradespeople. The few structures which remain standing seem far too risky to explore, liable to crumble at any moment.",
-          "roomTitle": "SEGEBERG CASTLE (Merchants Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 315,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE (Warebeth Lane)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 324,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 302,
-          "floorId": 19,
-          "roomDescription": "Evidence of the former splendor of Segeberg Castle is seen on this wide road, iterated by small dirt patches on the sides, some of which still hold trees. The ruins of buildings run along both sides of the road, elegant architectural details visible decorating crumbling stone structures. Weeds grow through the cracks in the cobblestone, as nature slowly reclaims the castle town.",
-          "roomTitle": "SEGEBERG CASTLE (Segeberg Parade)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 146,
-          "floorId": 19,
-          "roomDescription": "The ivy covered walls of the castle open up toward a gate facing the mountains to the west, and a rickety wooden bridge leads across the moat back toward the mountains. The structures here tell the tale of a rich history, and though they are now deteriorating, evidence of their past splendor surrounds you. Ornately carved gargoyles detail the crumbling buildings, many of which are coated in moss or obscured by ivy. Weeds poke through the spaces in between the cobblestones, slowly reclaiming the castle for nature.",
-          "roomTitle": "SEGEBERG CASTLE (West Gate interior)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "145": "Leave"
-          }
-        },
-        {
-          "roomId": 329,
-          "floorId": 19,
-          "roomDescription": "",
-          "roomTitle": "SEGEBERG CASTLE",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge5_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 301,
-          "floorId": 19,
-          "roomDescription": "Evidence of the former splendor of Segeberg Castle is seen on this wide road, iterated by small dirt patches on the sides, some of which still hold trees. The ruins of buildings run along both sides of the road, elegant architectural details visible decorating crumbling stone structures. Weeds grow through the cracks in the cobblestone, as nature slowly reclaims the castle town.",
-          "roomTitle": "SEGEBERG CASTLE (Segeberg Parade)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge4_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "07548a1b-c231-4a7f-838e-238a044ec513",
-      "id": 14,
-      "rawMatrixCsv": "70u|69,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 70,
-          "floorId": 14,
-          "roomDescription": "Three rows of lockers occupy this small space, providing a place for House Members to store items which they are not currently using.",
-          "roomTitle": "HOUSE OF FIRTH (Locker Room)",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "480a18bc-c66c-4999-adc5-6b333345cc1f",
-      "id": 31,
-      "rawMatrixCsv": "278u|279d|277,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 278,
-          "floorId": 31,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "49c1d7b2-ee46-4771-bf55-d42fcb2dfed2",
-      "id": 35,
-      "rawMatrixCsv": "371,343d|342,362,,,,,\n,,363,368,,,,\n,,364,367,,,,\n,,365,366,,,,\n,,369,370,372,,,\n,,373,374,375,,,\n",
-      "roomModels": [
-        {
-          "roomId": 368,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 364,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 362,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "MANOR HOUSE (Second Floor Hallway)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 370,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 373,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 365,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 369,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 372,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 363,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 375,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 374,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 343,
-          "floorId": 35,
-          "roomDescription": "The second floor provides housing to house residents and guests of the house. A balcony lines three sides of the main hall on the second floor, providing access to various living areas. The floor creaks slightly as you step on it, constructed of wooden planks many years ago. Large, comfortable rooms dominate this floor, benefitting from the heat rising from the downstairs fireplaces and kitchen.",
-          "roomTitle": "MANOR HOUSE STAIRCASE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 371,
-          "floorId": 35,
-          "roomDescription": "The second floor is sufficiently elevated above the Manor House wall to provide an unobstructed attack point against any potential invading forces. Here, small windows are manned by archers during any attack, and a spiral staircase leads upward to one of the main guard towers of the Manor House.",
-          "roomTitle": "MANOR HOUSE (Western Defense)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 367,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 366,
-          "floorId": 35,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "25c32e75-8326-46c9-a203-f9c0b06a7b02",
-      "id": 2,
-      "rawMatrixCsv": "18,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n15,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n14,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n13d|3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 13,
-          "floorId": 2,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 15,
-          "floorId": 2,
-          "roomDescription": "Nothing to see here except for jars and jars filled with excriment.",
-          "roomTitle": "LIKWID\u0027S SMEGMA STORAGE ROOM",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 14,
-          "floorId": 2,
-          "roomDescription": "You must enter Likwid\u0027s House of Wonders on all fours, through a dog door to the north.",
-          "roomTitle": "LIKWID\u0027S HOUSE OF WONDERS (Entrance)",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 17,
-          "floorId": 2,
-          "roomDescription": "LIKWID\u0027S FAVORITE PLACE TO RELAX (WITH MEN)",
-          "roomTitle": "LIKWID\u0027S MALE ONLY TURKISH BATHHOUSE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 16,
-          "floorId": 2,
-          "roomDescription": "A supply closet holding a lot of bleach and cleaning products needed to keep the filthy bathhouse to the north respectably clean.",
-          "roomTitle": "LIKWID\u0027S BATHHOUSE CLEANING SUPPLY CLOSET",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 18,
-          "floorId": 2,
-          "roomDescription": "The lair of dog dick has been reached. Game over.",
-          "roomTitle": "DOG DICK LAIR",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "62b839da-c66d-4036-b84d-ee77866c9256",
-      "id": 6,
-      "rawMatrixCsv": "30d|29u|31,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 30,
-          "floorId": 6,
-          "roomDescription": "Just below the top of the granite staircase, a large number of stairs are below you leading back to the town. The town square can be seen almost directly below, and this vantage point allows views all the way outward to the town walls. Two guard towers built into the corners of the Manor House wall can be seen above, permanently staffed by archers.",
-          "roomTitle": "MANOR HOUSE STAIRS",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "deee81d4-55fc-449d-a0b0-272120d57d3d",
-      "id": 17,
-      "rawMatrixCsv": "102,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 102,
-          "floorId": 17,
-          "roomDescription": "In this incredibly small space, an elderly shopkeeper stands behind the counter. The walls are decorated with several simple landscape paintings, and a vast astronomical chart. ",
-          "roomTitle": "HAVEN RARE ITEMS STORE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "101": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "86db752f-70da-4060-9bb8-163c82dfdb80",
-      "id": 29,
-      "rawMatrixCsv": "272d|273u|271,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 272,
-          "floorId": 29,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "f6b3a20d-dc00-4be3-bb86-24ef9196a4a7",
-      "id": 15,
-      "rawMatrixCsv": "71u|57,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 71,
-          "floorId": 15,
-          "roomDescription": "The cellar provides storage space for the food and drink requirements of the House. Stone bricks carved from granite line the walls, forming the foundation of the House. Various tools used for gardening and repairs can be seen leaning against a wall. A weapons locker can also be seen containing weapons owned by the House.",
-          "roomTitle": "HOUSE OF LANFAIR (Cellar)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "76318f69-460f-4bfb-b455-4f150d02cf07",
-      "id": 5,
-      "rawMatrixCsv": "29d|28u|30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 29,
-          "floorId": 5,
-          "roomDescription": "You currently stand at the midpoint of a long staircase leading up to the Manor House, lined with small stone lion statues. Above, guards can be noticed keeping a watchful eye in your direction as you move forward.",
-          "roomTitle": "MANOR HOUSE STAIRS",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "13215a64-b0dc-4f80-b4c7-c7f23a65b34f",
-      "id": 7,
-      "rawMatrixCsv": "33,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n31d|30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 32,
-          "floorId": 7,
-          "roomDescription": "Just to the side of the Manor House entrance, you notice guards in the towers carefully monitoring your movements. Following the wall of the Manor House, you can see the main entrance to your north, and the long staircase leading to town to your south.",
-          "roomTitle": "MANOR HOUSE WEST WALL",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 33,
-          "floorId": 7,
-          "roomDescription": "An intimidating iron gate blocks the entrance to the manor house, with a large gold-plated lions head design in the middle of it. The gate is fastened to the thick stone walls surrounding the entire house, and the whole of the town can be seen when looking in the other direction. Two torches are placed at either side of the gate, illuminating the entrance to the house when necessary. Inside the gate, a marble fountain can be seen, with four lions heads spouting water from their mouths.",
-          "roomTitle": "MANOR HOUSE MAIN GATE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "339": "gate"
-          }
-        },
-        {
-          "roomId": 31,
-          "floorId": 7,
-          "roomDescription": "Standing at the top of the Manor House granite staircase, a twenty foot high fortification forming the western wall of the Manor House is immediately in front of you. Below, the stairs descend steeply enough that it is impossible to see their end. You notice guards to the north, waiting near the main entrance of the Manor House.",
-          "roomTitle": "MANOR HOUSE WEST WALL",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "fe7753a9-9d34-40f9-ad1c-dee8ac48b518",
-      "id": 12,
-      "rawMatrixCsv": "254,67d|255,68,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 254,
-          "floorId": 12,
-          "roomDescription": "A small counter serves as the house item shop, stocking only a few simple items often needed by local hunters and travelers.",
-          "roomTitle": "HAUGSEITH HOUSE (Item Shop)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 67,
-          "floorId": 12,
-          "roomDescription": "A giant taxidermied eagle hangs from the ceiling facing the front door. Massive wooden logs forming the main structure of the house can be seen framing the room. A smell of burning firewood permeates the air, and several sets of heavy workboots sit next to a bench, caked in mud. To the east, a room containing a large cast iron stove can be seen, and to the west, a small counter offering a few basic items for sale. You also notice a small sign hanging above the bench.",
-          "roomTitle": "HAUGSEITH HOUSE (Entryway)",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "52": "Leave"
-          }
-        },
-        {
-          "roomId": 68,
-          "floorId": 12,
-          "roomDescription": "Several wooden benches and upholstered chairs surround this room, providing a space to relax for hunters and warriors who have grown weary traveling through the forest. A heavily used cast iron stove can be seen close to the center of the room, with several stacks of firewood sitting on the ground next to it. On the wall, you can see an oil painting of a hunting party standing in front of a mountainous landscape. ",
-          "roomTitle": "HAUGSEITH HOUSE (Main Room)",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "47208e8e-e96c-4c62-b507-7b8458ff5017",
-      "id": 8,
-      "rawMatrixCsv": ",64d|376,63,61,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n60,59,57u|62d|71,58,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 64,
-          "floorId": 8,
-          "roomDescription": "Often the most well attended room in all of the House, the wood paneling covering the walls here is adorned by detailed carvings, many featuring historic battle scenes described by Patrons of the House, some truthful, and many fictional. Several heads of slain creatures can be seen mounted high on the walls, preserved as trophies. The bar was built from the largest tree ever to be felled within the lands of the town and the Manor, a gift from the Manor House to the House of Lanfair.",
-          "roomTitle": "HOUSE OF LANFAIR (House Pub)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 61,
-          "floorId": 8,
-          "roomDescription": "A marvel of architecture, this large circular room is surrounded on all sides by glass windows. Toward the roof, windows can be retracted by House staff to provide Members outstanding views of the cosmos in fine weather. Several astronomical and scientific devices can be seen throughout the room, and guest scientists are frequently invited to the House for the purpose of furthering their research. To the west, a small, nondescript doorway leads to the Member locker room.",
-          "roomTitle": "HOUSE OF LANFAIR (Observatory)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 60,
-          "floorId": 8,
-          "roomDescription": "A large, brick-paved terrace provides for additional entertainment space during the most well attended events held at the House, or alternatively a quiet discussion space for Members to contemplate important matters amongst themselves. Several oil lanterns are placed around the terrace, should light be required. The House wall provides a degree of privacy from the outside world, constructed to protect the peace of the dignified Members of the House, many of whom occupy the most powerful positions in town.",
-          "roomTitle": "HOUSE OF LANFAIR (Terrace)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 58,
-          "floorId": 8,
-          "roomDescription": "With the largest collection of manuscripts in town, you are surrounded on four sides by walls of books. Ladders can be used by those seeking access to particular manuscripts, but Members typically seek the assistance of the House Librarian when retrieving materials. Four dark wooden desks can be seen on the eastern side of the library, providing space for those who wish to write. A further three upholstered chairs are seen on the opposite side of the room, in front of tilted wooden desks, providing a more comfortable place for patrons to sit and read the many manuscripts in the House collection. Through an archway to the north, supported by Corinthian columns, you can see a circular room surrounded by glass windows.",
-          "roomTitle": "HOUSE OF LANFAIR (Library)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 63,
-          "floorId": 8,
-          "roomDescription": "Rows of wooden lockers sit on opposite sides of one another in this fairly narrow room. Here, each Member is provided with enough space to store any personal belongings that are unneeded, or too cumbersome to carry.",
-          "roomTitle": "HOUSE OF LANFAIR (Member Locker Room)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 57,
-          "floorId": 8,
-          "roomDescription": "Standing in the foyer of the main entrance of the House of Lanfair, a stately marble staircase can be seen in front of you leading to the second level. On either side of the staircase, jade Gargoyles stand guard, carved eight centuries ago by the renowned artist Fabianus. A crystal chandelier hangs from the ceiling above, at least fifteen feet in diameter, ringed by twenty oil burning candles which are attended to daily by the House staff. Looking to the west, a large ballroom can be seen, with a rectangular oak dining table placed at the middle. Through the doorway to the east, one can see a wood paneled library containing rows of books extending up until the ceiling. Immediately to the north, and under the staircase, the entrance to the Member locker room can be seen.",
-          "roomTitle": "HOUSE OF LANFAIR (Foyer)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {
-            "21": "Leave"
-          }
-        },
-        {
-          "roomId": 59,
-          "floorId": 8,
-          "roomDescription": "The dining room contains wood paneled walls extending halfway to the ceiling, with green paint covering the remainder of the walls. Portraits of every Presiding Member of the House of Lanfair line the walls above the wood paneling, commissioned at the end of their service. The large, oak dining table is surrounded by thirty chairs, used only occasionally for the most formal dinners occurring within the House. To the north, a small archway held by Corinthian columns leads toward the House pub, and to the west, glass doors lead to a brick paved terrace.",
-          "roomTitle": "HOUSE OF LANFAIR (Main Dining Room)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "dd206ce6-18f7-47ad-a806-74a47181d04a",
-      "id": 3,
-      "rawMatrixCsv": "19u|1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 19,
-          "floorId": 3,
-          "roomDescription": "In a large underground area, goods for sale by local merchants are piled on all sides. A musty smell pervades the giant, poorly lit space, and crates are stacked along the walls on all sides.",
-          "roomTitle": "STOREHOUSE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "840e2c9b-6697-49ff-a6a2-cac79c33ccb6",
-      "id": 24,
-      "rawMatrixCsv": "253,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 253,
-          "floorId": 24,
-          "roomDescription": "Housed in the oldest building still standing in the town, this blacksmith shop has been in continual operation for centuries. Given the history of this shop, the proprietor has periodically discovered ancient weaponry while digging around the shop\u0027s expansive cellar, and occasionally puts these rare items up for sale.",
-          "roomTitle": "BLACKSMITH SHOP (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "238": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "d6052ba4-c245-4cce-8b2b-e4b1927d89b5",
-      "id": 27,
-      "rawMatrixCsv": "261,264,265,266,,,,,,,,,,\n262,263,,267,,,,,,,,,,\n,,,268,269u|270,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 265,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 262,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 261,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western8_zone"
-          ],
-          "enterExitNames": {
-            "260": "Leave"
-          }
-        },
-        {
-          "roomId": 266,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 264,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 269,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 267,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 263,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western8_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 268,
-          "floorId": 27,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "d36daa8c-8ea0-4270-a750-71c24bf81597",
-      "id": 32,
-      "rawMatrixCsv": "279u|280d|278,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 279,
-          "floorId": 32,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "cdd3abb9-66b4-4310-a14c-b6ee5c0fbba2",
-      "id": 1,
-      "rawMatrixCsv": "9,8,7,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n10,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n11,12,3u|13d|2,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 5,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 12,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 8,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 10,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 11,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 3,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 4,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 9,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 6,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 7,
-          "floorId": 1,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "7b28feb9-54d7-40f1-b36d-873f42575b71",
-      "id": 18,
-      "rawMatrixCsv": "133u|132,134,135,,,142,143,144,145,,,,,,,,,,,,,,,,,,,,\n,,136,,140,141,,,,,,,,,,,,,,,,,,,,,,,\n,,137,138,139,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 142,
-          "floorId": 18,
-          "roomDescription": "As you travel along this fairly flat pathway, mountain meadows surround you on all sides, with the steep Bloodridge Mountain Range rising sharply above to the west. The trail is somewhat overgrown, given the decline of Segeberg Castle over the years, but still very easily navigable.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 135,
-          "floorId": 18,
-          "roomDescription": "Thick, low lying vegetation surrounds the trail on all sides, making travel off the trail extremely difficult. The trail is lined with countless uneven rocks, leading to fatigue in even the strongest travelers. The mountain looms high above to the west, while the trail to the east continues over rough terrain. A small stone marker on the side of the road is carved with XXXIII.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 137,
-          "floorId": 18,
-          "roomDescription": "Thick, low lying vegetation surrounds the trail on all sides, making travel offthe trail extremely difficult. The trail is lined with countless uneven rocks,leading to fatigue in even the strongest travelers. The mountain looms highabove to the west, while the trail to the east continues over rough terrain.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 143,
-          "floorId": 18,
-          "roomDescription": "As you travel along this fairly flat pathway, mountain meadows surround you on all sides, with the steep Bloodridge Mountain Range rising sharply above to the west. The trail is somewhat overgrown, given the decline of Segeberg Castle over the years, but still very easily navigable.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 144,
-          "floorId": 18,
-          "roomDescription": "As you travel along this fairly flat pathway, mountain meadows surround you on all sides, with the steep Bloodridge Mountain Range rising sharply above to the west. The trail is somewhat overgrown, given the decline of Segeberg Castle over the years, but still very easily navigable.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 138,
-          "floorId": 18,
-          "roomDescription": "Thick, low lying vegetation surrounds the trail on all sides, making travel off the trail extremely difficult. The trail is lined with countless uneven rocks, leading to fatigue in even the strongest travelers. The mountain looms high above to the west, while the trail to the east continues over rough terrain. A small stone marker on the side of the road is carved with XXXVI.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 141,
-          "floorId": 18,
-          "roomDescription": "As you travel along this fairly flat pathway, mountain meadows surround you onall sides, with the steep Bloodridge Mountain Range rising sharply above to thewest. The trail is somewhat overgrown, given the decline of Segeberg Castle overthe years, but still very easily navigable. A small stone marker on the side of the trail is carved with XXXIX.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 134,
-          "floorId": 18,
-          "roomDescription": "Thick, low lying vegetation surrounds the trail on all sides, making travel off the trail extremely difficult. The trail is lined with countless uneven rocks, leading to fatigue in even the strongest travelers. The mountain looms high above to the west, while the trail to the east continues over rough terrain.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 136,
-          "floorId": 18,
-          "roomDescription": "Thick, low lying vegetation surrounds the trail on all sides, making travel offthe trail extremely difficult. The trail is lined with countless uneven rocks,leading to fatigue in even the strongest travelers. The mountain looms highabove to the west, while the trail to the east continues over rough terrain.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 133,
-          "floorId": 18,
-          "roomDescription": "Above, a steep staircase can be seen, ascending over a sheer cliff. The air is only slightly colder than the lower elevations here, but small patches of old snow can be seen above. Scrub like bushes grow thick here on all sides, encapsulating all of the terrain except the well worn trail.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 145,
-          "floorId": 18,
-          "roomDescription": "The ancient Segeberg Castle stands before you, surrounded by a wide moat. Though the castle is surrounded by numerous guard towers, they are seldom manned today, a consequence of centuries of the castle\u0027s decline. Ivy grows along most of the wall, and though you notice evidence of pathways in several directions, they have become overgrown and nearly impassible. The stagnant water in the moat has developed numerous lilypads, and a layer of algae can also be seen. A rickety wooden bridge leads over the moat into the castle.",
-          "roomTitle": "SEGEBERG CASTLE (West Gate)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "146": "gate"
-          }
-        },
-        {
-          "roomId": 140,
-          "floorId": 18,
-          "roomDescription": "Here, the road transitions between a rugged mountain trail and a pleasant, flat pathway connecting from Segeberg Castle. Travelers often choose to rest at this junction in preparation for the arduous journey over Bloodridge Mountain Pass. Segeberg Castle sits only a short distance to the east, offering some respite, though it has become mostly abandoned over the years.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 139,
-          "floorId": 18,
-          "roomDescription": "The trail here is only moderately steep, and just below this point it appears to significantly flatten out. Above, a daunting winding path is visible, leading to the infamous Bloodridge Mountain Pass.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "041f4e8a-bc7c-4814-95ce-a9278daf5cef",
-      "id": 28,
-      "rawMatrixCsv": "270d|269,271d|272,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 270,
-          "floorId": 28,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 271,
-          "floorId": 28,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "add3dc26-635b-4cc8-aa12-fb4d05936463",
-      "id": 36,
-      "rawMatrixCsv": "350u|348,,,\n",
-      "roomModels": [
-        {
-          "roomId": 350,
-          "floorId": 36,
-          "roomDescription": "Built into the ground of the mountain on which the Manor House sits, this room serves as a storehouse for food and drink. Constructing the room took an exceptional effort, involving manually chipping away at the rock until a suitably large underground space could be created. The temperature here remains fairly cool year round, making this an ideal place to store any perishable items. ",
-          "roomTitle": "MANOR HOUSE BUTTERY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "f2caa3a0-40bd-45ab-bbac-e13c31031fdb",
-      "id": 22,
-      "rawMatrixCsv": "211u|210,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 211,
-          "floorId": 22,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "Default Title, change with title command",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "3a931a59-096f-47c2-868c-3bdaa234c1b0",
-      "id": 37,
-      "rawMatrixCsv": "376u|64,,\n",
-      "roomModels": [
-        {
-          "roomId": 376,
-          "floorId": 37,
-          "roomDescription": "A large glowing device sits at the center of this small room, and transmissions about dog dicks can be heard coming through the device. From here, it is possible to communicate with shitlords in the outside world and exchange imgur links to fat people doing stupid shit.",
-          "roomTitle": "HOUSE OF LANFAIR (NEXUS RADIO ROOM)",
-          "roomTags": [],
-          "areaNames": [
-            "fancyhouse_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "3209e23a-59f2-414e-9736-b39f67e05dca",
-      "id": 25,
-      "rawMatrixCsv": "255u|67,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 255,
-          "floorId": 25,
-          "roomDescription": "Providing much cheaper and smaller lockers than those typically available at the houses in town, the downstairs locker room offers space to store a small number of items, though a fee must be paid each time the locker is accessed. A sign posted on the wall lists the fees, which differ based on the size of locker being sought.",
-          "roomTitle": "HAUGSEITH HOUSE (Locker Room)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "38400930-8a09-432b-98c7-c978412ec075",
-      "id": 9,
-      "rawMatrixCsv": "62d|57,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 62,
-          "floorId": 9,
-          "roomDescription": "On the upper level, six rooms are available to Members or guests in desire of rest. Behind these rooms and toward the back of the House, there are three further rooms, occupied by the most important House staff: the head butler, the head chef, and the librarian.",
-          "roomTitle": "HOUSE OF LANFAIR (Top of staircase)",
-          "roomTags": [],
-          "areaNames": [
-            "house_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "66503b92-bcd4-4cc5-a500-588843feadd7",
-      "id": 11,
-      "rawMatrixCsv": "66,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 66,
-          "floorId": 11,
-          "roomDescription": "Various metalworks can be seen hanging from the walls, including a wall devoted entirely to weaponry. The blacksmith can be seen operating a forge toward the back of the shop with the assistance of two apprentices. A wave of heat can occasionally be felt emanating from the furnace.",
-          "roomTitle": "BLACKSMITH\u0027S SHOP",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "2": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "c45f8553-d1d4-40c9-9729-d68e5f2969e2",
-      "id": 16,
-      "rawMatrixCsv": "98,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 98,
-          "floorId": 16,
-          "roomDescription": "Dried and cured meats hang from the ceiling and along the walls. A rack of sharp knives can be seen behind the counter, and leather and cloth aprons hang from several hooks on the wall.",
-          "roomTitle": "BUTCHER SHOP",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "2": "Leave"
-          }
-        }
-      ]
-    },
-    {
-      "name": "b8f542ec-0c54-4398-8d1a-8c3ed039ae10",
-      "id": 33,
-      "rawMatrixCsv": "281,280d|279,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 280,
-          "floorId": 33,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 281,
-          "floorId": 33,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "175f860e-2e9c-473f-aa77-a7d1d452e7c2",
-      "id": 30,
-      "rawMatrixCsv": "277u|278,,273u|272,,,,,,,,,\n276,275,274,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 277,
-          "floorId": 30,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 274,
-          "floorId": 30,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 275,
-          "floorId": 30,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 273,
-          "floorId": 30,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western9_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 276,
-          "floorId": 30,
-          "roomDescription": "A terrifying grotto surrounds you, lined with jagged, jet black rocks, and water can be heard flowing all around you. Bones appear to be scattered throughout the cave, a number of which appear human. The irregular shape of the caves carry sound in unpredictable directions, and determining the source of the sound is often extremely difficult. Occasionally, large rats can be seen scurrying around.",
-          "roomTitle": "BLACKSTONE CAVES",
-          "roomTags": [],
-          "areaNames": [
-            "western10_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "main",
-      "id": 0,
-      "rawMatrixCsv": ",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,193,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,192,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,191,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,190,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,189,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,184,185,186,187,188,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,183,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,182,181,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,179,180,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,178,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,177,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,,,,176,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,,,,,,,172,173,174,175,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n338,337,,,,,,,,,,,,,,,,,,,,,,171,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,336,335,,,,,,,,,,,,,,,,,,,,,170,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,334,,,,,,,,,,,,,,,,,,,,168,169,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,333,,,,,,,,,,,,,,,,,,,,167,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,128,,,,,,,,,,,,,,,,,,,165,166,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,127,,,,,,,,,,,,,,,,,,,164,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,126,125,,,,,,,,,,,,,,,,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,124,123,,,,,,,,,,,,,,,,,162,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,122,,,,,,,,,,,,,,,,,161,160,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,121,,,,,,,,,,,202,201,200,199,,,,159,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,120,119,,,,,,,,,,203,,197,198,,,,158,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,118,117,,,,,,,,,194,195,196,,154,155,156,157,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,116,115,,,,,,,147,148,,,,153,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,114,113,112,111,110,109,107,108,,,,,152,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,106,,52,,149,150,151,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,105,104,51,50,47,,,,,,,,,,,,,,,131,132d|133,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,46,,,,,,,,,,,,,97,129,130,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,45,,,,,,,,,,,,,96,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,44,,,,,,,,,,,,,95,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,43,,,,,,,,,,,,,94,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,34,35,72,73,74,75,76,,,85,86,87,,93,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,26,,,,,,77,78,,84,,88,,92,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,,,25,,,,,,,79,,83,,89,90,91,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,42,,,,2d|20u|3,,,,,,,80,81,82,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,99,41,40,39,38,37,36,23,1d|19,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,53,,210d|211,,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,101,100,54,55,212,,22,27,28u|29,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,56,103,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,225,224,223,,,213,,49,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,226,,220,219,218,214,215,216,217,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,229,227,228,221,,236,,,235,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,222,230,231,232,233,234,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,237,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,257,258,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,259,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n,,,,,,,,,,,,,,,260,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 168,
-          "floorId": 0,
-          "roomDescription": "Being relatively close to the foothills, the slight inclination of the terrain has caused the neighboring stream to form rapids. As the violently churning water smashes into rocks, a fine mist shrouds the area, and many varieties of mushrooms can be seen growing by the roadside, providing an attractive opportunity to forage.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 24,
-          "floorId": 0,
-          "roomDescription": "The bustling square gives way to a dead end side street, facing the giant cliffs and walls of the Manor House. On one side of the street, you see the Town Bank, and on the other, a stone storage house. ",
-          "roomTitle": "TORRIDON LANE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "65": "Bank"
-          }
-        },
-        {
-          "roomId": 150,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 81,
-          "floorId": 0,
-          "roomDescription": "This treacherous, steep road winds back and forth along a dangerous mountainside. Compared to the valley, the temperature feels significantly colder here. You notice caves dotting the mountainside, some of which appear to be inhabited by creatures.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 186,
-          "floorId": 0,
-          "roomDescription": "Widely spaced trees yield stunning views of the Bloodridge Mountain Range escarpment to the east, and the road surface is pleasantly smooth and even for traveling. A small stone marker can be seen on the side of the road with XLII carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 53,
-          "floorId": 0,
-          "roomDescription": "Three story stone buildings line this quiet street, which appear to be mostly residences. Coal smoke can be seen billowing upward from several of the homes.",
-          "roomTitle": "STORMARN LANE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 103,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "THE NORTHWAY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 36,
-          "floorId": 0,
-          "roomDescription": "The largest road in town, this east to west thoroughfare serves as the main parade ground leading to the town square. Directly to the east and high above, the Manor House can be seen as one walks toward the town square. Rows of elm trees flank either side of the road, planted on the town\u0027s two hundredth anniversary, and providing shade to the numerous benches built under them. Street performers and healers often choose to conduct their business here, appreciating the ample space and available shade.",
-          "roomTitle": "VICTORY ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 25,
-          "floorId": 0,
-          "roomDescription": "Gates can be seen just to the north on this cobblestone street, barely wide enough for two carriages to pass in either direction. Well kept yet simple stone homes sit on either side of the lane, providing a place to live for members of the peasantry. To the south, a large square can be seen in the distance, and to the east, the high inner walls of the Manor House. The cobblestones are well worn from the continuous traffic of carriages leaving town and returning from the countryside.",
-          "roomTitle": "CRAIGAVON LANE NORTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 23,
-          "floorId": 0,
-          "roomDescription": "Four uniformly shaped stone buildings stand before you, each operated by a different merchant. To the east, one can see the expansive town square, with the cliffs and walls of the Manor House behind it. ",
-          "roomTitle": "THE NEXUS",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 35,
-          "floorId": 0,
-          "roomDescription": "A broad stream flows here diagonally to the corner of the town wall, just to the east of the North Gate. A pool of gently flowing water can be seen at this part of the stream, serving as an ideal location to provide refreshment for horses or for swimming. The stream teems with fish, and the ground next to the stream is well worn from the frequent visits of those leaving or returning to the town.",
-          "roomTitle": "ABERGWAUN STREAM",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 201,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 161,
-          "floorId": 0,
-          "roomDescription": "At this section of road, the surroundings bear little evidence of human activity. Being some distance from any town and somewhat isolated, travelers usually work their way along this section of road with a high level of vigilance. The Bloodridge Mountain escarpment can be seen through the trees to the east, and the road appears to run mostly parallel to the mountains.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 78,
-          "floorId": 0,
-          "roomDescription": "This treacherous, steep road winds back and forth along a dangerous mountainside. Compared to the valley, the temperature feels significantly colder here. You notice caves dotting the mountainside, some of which appear to be inhabited by creatures.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 121,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 97,
-          "floorId": 0,
-          "roomDescription": "Standing at highest point of Bloodridge Mountain Road, you find yourself within the only mountain pass in the range for many miles. The temperature is frigid here, with the possibility of snow year round, and a glacier can be seen on a mountain high above. A small memorial stands here in honor of several townspeople who were ambushed and killed by creatures as they crossed this pass. You are able to see Bloodridge Mountain Road winding downward toward the west, and there appears to be a small settlement in the distance further downhill to the east.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN PASS",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 75,
-          "floorId": 0,
-          "roomDescription": "Off to the west, the road begins to enter a steep mountain range featuring sheer cliffs on which little vegetation grows. Toward the east, the North Gate of town lies ahead.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 91,
-          "floorId": 0,
-          "roomDescription": "A biting, howling wind roars across this hostile mountain terrain, open enough that you can easily make out the town below to the west, though a thick fog often shrouds the area and obscures its view. Winds have been known to occasionally reach hurricane force at this elevation, sometimes scouring the snow off higher slopes and loading it into massive snowdrifts.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 100,
-          "floorId": 0,
-          "roomDescription": "A narrow alleyway, the name Haven Alley commemorates the townspeople\u0027s victory over an invading force over one century ago at this very place. As the alley is far too narrow to allow the passage of horses or carriages, the residents were able to take advantage of this and repel the invaders.",
-          "roomTitle": "HAVEN ALLEY",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 231,
-          "floorId": 0,
-          "roomDescription": "As one of the busiest intersections in the town, second only to the Town Square, goods frequently travel through here, either on their way to one of the many warehouses on Brewery Lane, or bound for the merchants on the northern side of town. To the south, travelers come and go from the town through the South Gate. ",
-          "roomTitle": "BREWERY LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 177,
-          "floorId": 0,
-          "roomDescription": "The town of Hammoor, some distance to the north, regularly sends laborers to repair this remote, muddy section of road, as it is the main lifeline providing food supplies to the town. Though too remote to consider paving with stone or covering with gravel, laborers from the town of Hammoor have laid wooden planks here, keeping travelers above the mud. These must be regularly replaced due to being worn down from constant traffic.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 77,
-          "floorId": 0,
-          "roomDescription": "Off to the west, the road begins to enter a steep mountain range featuring sheer cliffs on which little vegetation grows. Toward the east, the North Gate of town lies ahead. A small stone marker on the side of the road is carved with VI.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 27,
-          "floorId": 0,
-          "roomDescription": "Eight life size lion statues line this small cobblestone lane, which has no other structures on it. Immediately to the east, the beginning of a large stone staircase can be seen, scaling the granite cliffs below the Manor House.",
-          "roomTitle": "KINGS LANE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 165,
-          "floorId": 0,
-          "roomDescription": "Bisecting deep wilderness, the road here was built alongside a wide stream flowing from high in the Bloodridge Mountains, as this provided one of the only relatively flat places to construct it. The sound of rushing water can be heard all along the road, fueled by melting glaciers high above.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 126,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 169,
-          "floorId": 0,
-          "roomDescription": "Being relatively close to the foothills, the slight inclination of the terrain has caused the neighboring stream to form rapids. As the violently churning water smashes into rocks, a fine mist shrouds the area, and many varieties of mushrooms can be seen growing by the roadside, providing an attractive opportunity to forage. A small stone marker can be seen on the side of the road with XXVII carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 72,
-          "floorId": 0,
-          "roomDescription": "Off to the west, the road begins to enter a steep mountain range featuring sheer cliffs on which little vegetation grows. Toward the east, the North Gate of town lies ahead.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 28,
-          "floorId": 0,
-          "roomDescription": "Above you is a long stone staircase carved into the cliffs edge, which leads tothe main western entrance of the Manor House. You are able to see a set of atleast fifty steps, after which they become impossible to count from here. Anelaborately carved wooden railing follows the staircase upward, preventing onefrom falling off the steep cliff. To the west, the statue lined Kings Lane can be seen leading back to town.",
-          "roomTitle": "MANOR HOUSE STAIRS",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 39,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "VICTORY ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 104,
-          "floorId": 0,
-          "roomDescription": "A narrow pathway continues through the thick woods, and footprints are visible in the mud.",
-          "roomTitle": "EDGAR\u0027S WOODS",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 190,
-          "floorId": 0,
-          "roomDescription": "In the immediate vicinity of the Town of Hammoor, the road here is paved with smooth stones, many taken from riverbeds. The town\u0027s main gate and barbican can be seen some distance to the north, sitting immediately next to the sheer cliffs of the Bloodridge Mountain escarpment.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 175,
-          "floorId": 0,
-          "roomDescription": "The town of Hammoor, some distance to the north, regularly sends laborers to repair this remote, muddy section of road, as it is the main lifeline providing food supplies to the town. Though too remote to consider paving with stone or covering with gravel, laborers from the town of Hammoor have laid wooden planks here, keeping travelers above the mud. These must be regularly replaced due to being worn down from constant traffic. A small stone marker can be seen on the side of the road with XXXIII carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 337,
-          "floorId": 0,
-          "roomDescription": "From this stone covered beach, Toft Island can be seen in the distance. The freshwater lake draws animals from the surrounding forest, seeking to quench their thirst or hunt for fish.",
-          "roomTitle": "TOFT ISLAND LAKE SHORE",
-          "roomTags": [],
-          "areaNames": [
-            "toft2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 212,
-          "floorId": 0,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "THE NORTHWAY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 258,
-          "floorId": 0,
-          "roomDescription": "The Blackstone Cave Road connects the southern gate of the town with the Blackstone Caves, a series of caverns carved into the rock of the Bloodridge Mountains.",
-          "roomTitle": "BLACKSTONE CAVE ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 34,
-          "floorId": 0,
-          "roomDescription": "As the road transitions here between cobblestone and dirt, dense forest can be seen on three sides. An open area sits to the side and provides a waiting space for those seeking entrance to the town. The outer walls of the town can be seen, with only the Manor House visible within the town on the high cliffs above. A small sign reads \"Abergwaun Stream\", with an arrow pointing toward the east.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 163,
-          "floorId": 0,
-          "roomDescription": "Bisecting deep wilderness, the road here was built alongside a wide stream flowing from high in the Bloodridge Mountains, as this provided one of the only relatively flat places to construct it. The sound of rushing water can be heard all along the road, fueled by melting glaciers high above. A small stone marker can be seen on the side of the road with XXI carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 41,
-          "floorId": 0,
-          "roomDescription": "The ceremonial main gate of the city, an immense stone arch guards the entrance to the city. When standing before the West Gate, one can see the cliffs of the Manor House on the opposite side of town, offering an intimidating impression of power to all those who enter the town. Being the widest entrance to the town, the most heavy fortifications can be seen here, with the gate often kept closed when not in use. The walls surrounding the West Gate bear countless pock marks from attacks on the town, and a wide, open landscape can be seen past the gate extending many miles.",
-          "roomTitle": "WEST GATE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 335,
-          "floorId": 0,
-          "roomDescription": "From this stone covered beach, Toft Island can be seen in the distance. The freshwater lake draws animals from the surrounding forest, seeking to quench their thirst or hunt for fish.",
-          "roomTitle": "TOFT ISLAND LAKE SHORE",
-          "roomTags": [],
-          "areaNames": [
-            "toft2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 88,
-          "floorId": 0,
-          "roomDescription": "A biting, howling wind roars across this hostile mountain terrain, open enough that you can easily make out the town below to the west, though a thick fog often shrouds the area and obscures its view. Winds have been known to occasionally reach hurricane force at this elevation, sometimes scouring the snow off higher slopes and loading it into massive snowdrifts.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 51,
-          "floorId": 0,
-          "roomDescription": "A narrow pathway continues through the thick woods, and footprints are visible in the mud. A wooden sign carved with \"House\" points north.",
-          "roomTitle": "EDGAR\u0027S WOODS",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 336,
-          "floorId": 0,
-          "roomDescription": "From this stone covered beach, Toft Island can be seen in the distance. The freshwater lake draws animals from the surrounding forest, seeking to quench their thirst or hunt for fish.",
-          "roomTitle": "TOFT ISLAND LAKE SHORE",
-          "roomTags": [],
-          "areaNames": [
-            "toft2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 222,
-          "floorId": 0,
-          "roomDescription": "A fairly wide, somewhat industrial thoroughfare, many tradespeople and those of the merchant class operate businesses along this wide lane, which offers close access to the South Gate, and is anchored by the town brewery. Large, simple stone structures line the road, mainly used as warehouses, though some are used to house animals and some are even used for manufacturing various goods. Double wooden doors, at least twice as high as the height of an average person, mark the entrance to these mostly identical looking buildings.",
-          "roomTitle": "BREWERY LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 115,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 44,
-          "floorId": 0,
-          "roomDescription": "A thick forest envelops your surroundings, obscuring whatever may lie in the distance. Creatures can occasionally be heard rustling through the leaves and branches, but they are not always easily seen. A small stone marker can be seen on the side of the road, with III carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 111,
-          "floorId": 0,
-          "roomDescription": "A constant slope rises toward the west, gradually rising in elevation above the swamps below. Toward the east, the forest appears much thicker, and the sound of frogs can be heard.",
-          "roomTitle": "EDGAR\u0027S WOODS (Toft Island Road)",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 227,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "SUNDS LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 180,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "\u003cPLACEHOLDER\u003e",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 54,
-          "floorId": 0,
-          "roomDescription": "Three story stone buildings line this quiet street, which appear to be mostly residences. Coal smoke can be seen billowing upward from several of the homes.",
-          "roomTitle": "STORMARN LANE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 120,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 109,
-          "floorId": 0,
-          "roomDescription": "A constant slope rises toward the west, gradually rising in elevation above the swamps below. Toward the east, the forest appears much thicker, and the sound of frogs can be heard.",
-          "roomTitle": "EDGAR\u0027S WOODS (Toft Island Road)",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 1,
-          "floorId": 0,
-          "roomDescription": "Before you is an immense town square, carefully paved with cobblestone and surrounded by ornate buildings. On the southern side of the square, space for merchants\u0027 tents is provided, and on the western side, a large open area suitable for large gatherings. To the east, the massive fortified walls of the Manor House are notable, standing above steep cliffs. Surrounding the square are a number of businesses, as well as homes of some of the wealthiest merchants in town.",
-          "roomTitle": "TOWN SQUARE",
-          "roomTags": [],
-          "areaNames": [
-            "lobby"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 259,
-          "floorId": 0,
-          "roomDescription": "The Blackstone Cave Road connects the southern gate of the town with the Blackstone Caves, a series of caverns carved into the rock of the Bloodridge Mountains.",
-          "roomTitle": "BLACKSTONE CAVE ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 210,
-          "floorId": 0,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "THE NORTHWAY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 114,
-          "floorId": 0,
-          "roomDescription": "On this large hill, widely spaced pine trees cover the landscape, and theotherwise smooth slope is broken up by a number of horizontal rock outcroppings,some of which contain caves. Grass, shrubs, and bushes with wild berries can begrowing between the pine trees. Small paths heading off the main road can beseen along the route.",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 96,
-          "floorId": 0,
-          "roomDescription": "A path thick with ice makes travel extremely difficult at this high elevation, with deep snowpack seen on all sides. Maintaining your footing is difficult on the ice, but leaving the road would be even more challenging, as the unpacked snow causes one to sink waist deep or more with each step. The only vegetation growing here is in the form of stunted trees, many of which have branches on only one side from being constantly battered by high winds.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 228,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "SUNDS LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 199,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 101,
-          "floorId": 0,
-          "roomDescription": "A curious looking doorway, nearly obscured by the growth of thick vines of ivy, can be seen in front of you at the end of this dead end alley. It appears to be unlocked.",
-          "roomTitle": "HAVEN ALLEY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "102": "doorway"
-          }
-        },
-        {
-          "roomId": 333,
-          "floorId": 0,
-          "roomDescription": "From this stone covered beach, Toft Island can be seen in the distance. The freshwater lake draws animals from the surrounding forest, seeking to quench their thirst or hunt for fish.",
-          "roomTitle": "TOFT ISLAND LAKE SHORE",
-          "roomTags": [],
-          "areaNames": [
-            "toft2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 185,
-          "floorId": 0,
-          "roomDescription": "Widely spaced trees yield stunning views of the Bloodridge Mountain Range escarpment to the east, and the road surface is pleasantly smooth and even for traveling.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 219,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "WYK LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 95,
-          "floorId": 0,
-          "roomDescription": "A path thick with ice makes travel extremely difficult at this high elevation, with deep snowpack seen on all sides. Maintaining your footing is difficult on the ice, but leaving the road would be even more challenging, as the unpacked snow causes one to sink waist deep or more with each step. The only vegetation growing here is in the form of stunted trees, many of which have branches on only one side from being constantly battered by high winds. A small stone marker on the side of the road is carved with XXIV.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 194,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insectsabound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 49,
-          "floorId": 0,
-          "roomDescription": "Row houses line the lane here, many occupied by townspeople closely connected to the Manor House. Most of the homes feature small wrought iron gates, and stand two levels high. A number of homes have potted plants growing from their balconies and windows.",
-          "roomTitle": "CRAIGAVON LANE SOUTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 40,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "VICTORY ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 76,
-          "floorId": 0,
-          "roomDescription": "Off to the west, the road begins to enter a steep mountain range featuring sheer cliffs on which little vegetation grows. Toward the east, the North Gate of town lies ahead.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 156,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 74,
-          "floorId": 0,
-          "roomDescription": "Off to the west, the road begins to enter a steep mountain range featuring sheer cliffs on which little vegetation grows. Toward the east, the North Gate of town lies ahead. A small stone marker on the side of the road is carved with III.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 198,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 37,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "VICTORY ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 183,
-          "floorId": 0,
-          "roomDescription": "The land transitions at this point on the road, with a fairly sparse forest growing to the north, and a very dense forest to the south. The northern forests have been logged for years by residents of Hammoor, renowned for their woodworking skills. The town also relies heavily on firewood for fuel, as little coal can be found in the surrounding area. A small stone marker can be seen on the side of the road with XXXIX carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 213,
-          "floorId": 0,
-          "roomDescription": "Newly created room. Set a new description with the desc command.",
-          "roomTitle": "THE NORTHWAY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 119,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 90,
-          "floorId": 0,
-          "roomDescription": "A biting, howling wind roars across this hostile mountain terrain, open enough that you can easily make out the town below to the west, though a thick fog often shrouds the area and obscures its view. Winds have been known to occasionally reach hurricane force at this elevation, sometimes scouring the snow off higher slopes and loading it into massive snowdrifts.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 155,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 116,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 47,
-          "floorId": 0,
-          "roomDescription": "A thick forest envelops your surroundings, obscuring whatever may lie in the distance. Creatures can occasionally be heard rustling through the leaves and branches, but they are not always easily seen. A small stone marker can be seen on the side of the road with VI carved into it. You also notice a muddy pathway leading west.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 179,
-          "floorId": 0,
-          "roomDescription": "The town of Hammoor, some distance to the north, regularly sends laborers to repair this remote, muddy section of road, as it is the main lifeline providing food supplies to the town. Though too remote to consider paving with stone or covering with gravel, laborers from the town of Hammoor have laid wooden planks here, keeping travelers above the mud. These must be regularly replaced due to being worn down from constant traffic.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 92,
-          "floorId": 0,
-          "roomDescription": "A path thick with ice makes travel extremely difficult at this high elevation, with deep snowpack seen on all sides. Maintaining your footing is difficult on the ice, but leaving the road would be even more challenging, as the unpacked snow causes one to sink waist deep or more with each step. The only vegetation growing here is in the form of stunted trees, many of which have branches on only one side from being constantly battered by high winds. A small stone marker on the side of the road is carved with XXI.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 187,
-          "floorId": 0,
-          "roomDescription": "Widely spaced trees yield stunning views of the Bloodridge Mountain Range escarpment to the east, and the road surface is pleasantly smooth and even for traveling.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 80,
-          "floorId": 0,
-          "roomDescription": "This treacherous, steep road winds back and forth along a dangerous mountainside. Compared to the valley, the temperature feels significantly colder here. You notice caves dotting the mountainside, some of which appear to be inhabited by creatures. A small stone marker on the side of the road is carved with IX.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 338,
-          "floorId": 0,
-          "roomDescription": "From this stone covered beach, Toft Island can be seen in the distance. The freshwater lake draws animals from the surrounding forest, seeking to quench their thirst or hunt for fish.",
-          "roomTitle": "TOFT ISLAND LAKE SHORE",
-          "roomTags": [],
-          "areaNames": [
-            "toft2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 129,
-          "floorId": 0,
-          "roomDescription": "Near the Bloodridge Mountain pass, the arid eastern side of the range, whilefrigid, holds far less snow than the western slopes. Stunted pines grow in thesurrounding area, never growing more than a few feet due to being constantlybattered by heavy winds. A steep trail winds downward, while immediately above,the top of the pass is visible. A small stone marker on the side of the road is carved with XXVII.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 232,
-          "floorId": 0,
-          "roomDescription": "The smell of brewing beer fills the air as you stand in front of the town brewery, which operates year round, every day of the week. Built around the same time that the town was founded, a small stone aqueduct was custom built to continually bring spring water from the Bloodridge Mountains directly into the brewery. Along with hops and barley grown in the agricultural lands to the west of town, the mix is allowed to ferment in large wooden containers and then slightly aged in the brewery cellar before it is ready for consumption.",
-          "roomTitle": "BREWERY LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 55,
-          "floorId": 0,
-          "roomDescription": "The winding Stormarn Lane continues past a series of simple homes, each appearing inhabited. Being some distance from Victory Road, this relatively quiet area has always been among the top choices of the townspeople to establish their households.",
-          "roomTitle": "STORMARN LANE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 226,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "PARADOX CRESCENT",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 171,
-          "floorId": 0,
-          "roomDescription": "With the road passing through a boggy landscape, dead trees can be seen everywhere, having rotten at the roots. An unpleasant dank, musty smell from rotting wood hovers over the area. Since the road provides a relatively dry and smooth surface to travel along, it is not only used by travelers, but nearly every beast of the forest as well.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 167,
-          "floorId": 0,
-          "roomDescription": "Being relatively close to the foothills, the slight inclination of the terrain has caused the neighboring stream to form rapids. As the violently churning water smashes into rocks, a fine mist shrouds the area, and many varieties of mushrooms can be seen growing by the roadside, providing an attractive opportunity to forage.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 130,
-          "floorId": 0,
-          "roomDescription": "Near the Bloodridge Mountain pass, the arid eastern side of the range, whilefrigid, holds far less snow than the western slopes. Stunted pines grow in thesurrounding area, never growing more than a few feet due to being constantlybattered by heavy winds. A steep trail winds downward, while immediately above,the top of the pass is visible.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 188,
-          "floorId": 0,
-          "roomDescription": "Widely spaced trees yield stunning views of the Bloodridge Mountain Range escarpment to the east, and the road surface is pleasantly smooth and even for traveling.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 184,
-          "floorId": 0,
-          "roomDescription": "Widely spaced trees yield stunning views of the Bloodridge Mountain Range escarpment to the east, and the road surface is pleasantly smooth and even for traveling. A small sign facing south can be seen, with \"Hammoor - 9\" written on it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 107,
-          "floorId": 0,
-          "roomDescription": "The road splits in two directions at this swampy junction. A sign marks the road toward Toft Island to the west, while the path to the east continues more deeply into forest swamps.",
-          "roomTitle": "EDGAR\u0027S WOODS",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 122,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 154,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north. A small stone marker can be seen on the side of the road with XII carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 178,
-          "floorId": 0,
-          "roomDescription": "The town of Hammoor, some distance to the north, regularly sends laborers to repair this remote, muddy section of road, as it is the main lifeline providing food supplies to the town. Though too remote to consider paving with stone or covering with gravel, laborers from the town of Hammoor have laid wooden planks here, keeping travelers above the mud. These must be regularly replaced due to being worn down from constant traffic. A small stone marker can be seen on the side of the road with XXXVI carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 117,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 118,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 127,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 193,
-          "floorId": 0,
-          "roomDescription": "One of the closest allies of the MAIN TOWN, the Town of Hammoor is nestled within a glacial cirque carved out of the Bloodridge Mountains millions of years ago. This location provides the town with a natural defense, preventing invading forces from attacking from the east. As the surrounding area is mostly forested, or contains poor quality soil, Hammoor relies heavily on its bustling trade with the MAIN TOWN for food and agricultural products. A stone barbican guards the entrance to the city.",
-          "roomTitle": "TOWN OF HAMMOOR (Main Gate)",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {
-            "204": "gate"
-          }
-        },
-        {
-          "roomId": 195,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 125,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 197,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 89,
-          "floorId": 0,
-          "roomDescription": "A biting, howling wind roars across this hostile mountain terrain, open enough that you can easily make out the town below to the west, though a thick fog often shrouds the area and obscures its view. Winds have been known to occasionally reach hurricane force at this elevation, sometimes scouring the snow off higher slopes and loading it into massive snowdrifts. A small stone marker on the side of the road is carved with XVIII.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 176,
-          "floorId": 0,
-          "roomDescription": "The town of Hammoor, some distance to the north, regularly sends laborers to repair this remote, muddy section of road, as it is the main lifeline providing food supplies to the town. Though too remote to consider paving with stone or covering with gravel, laborers from the town of Hammoor have laid wooden planks here, keeping travelers above the mud. These must be regularly replaced due to being worn down from constant traffic.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 173,
-          "floorId": 0,
-          "roomDescription": "With the road passing through a boggy landscape, dead trees can be seen everywhere, having rotten at the roots. An unpleasant dank, musty smell from rotting wood hovers over the area. Since the road provides a relatively dry and smooth surface to travel along, it is not only used by travelers, but nearly every beast of the forest as well.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 260,
-          "floorId": 0,
-          "roomDescription": "The Blackstone Cave Road connects the southern gate of the town with the Blackstone Caves, a series of caverns carved into the rock of the Bloodridge Mountains. Here, you see a cave entrance.",
-          "roomTitle": "BLACKSTONE CAVE ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "261": "cave"
-          }
-        },
-        {
-          "roomId": 224,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "PARADOX CRESCENT",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 84,
-          "floorId": 0,
-          "roomDescription": "The higher elevations of the western slopes of Bloodridge Mountain Road receive frequent snowfalls,and a coating of old snow covers the surrounding terrain. Along this steepsection of road, rockfalls are common, which can often make the road impassibleuntil cleared.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 216,
-          "floorId": 0,
-          "roomDescription": "Row houses line the lane here, many occupied by townspeople closely connected to the Manor House. Most of the homes feature small wrought iron gates, and stand two levels high. A number of homes have potted plants growing from their balconies and windows.",
-          "roomTitle": "CRAIGAVON LANE SOUTH",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 172,
-          "floorId": 0,
-          "roomDescription": "With the road passing through a boggy landscape, dead trees can be seen everywhere, having rotten at the roots. An unpleasant dank, musty smell from rotting wood hovers over the area. Since the road provides a relatively dry and smooth surface to travel along, it is not only used by travelers, but nearly every beast of the forest as well. A small stone marker can be seen on the side of the road with XXX carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 148,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 99,
-          "floorId": 0,
-          "roomDescription": "Traffic flows regularly along this wide road, most commonly used by farmers in the plains to bring their crops to town. Beyond the plains, rolling foothills can be seen, commonly used as pasture land. The Abergwaun Stream can be seen in the distance, bisecting the farmland, and is used by many of the farms for irrigation.",
-          "roomTitle": "WESTERN PLAINS ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 108,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 203,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 124,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 73,
-          "floorId": 0,
-          "roomDescription": "Here, the road crosses the Abergwaun stream, which has its source high in the Bloodridge Mountains. Toward the east, the North Gate of town lies ahead.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD (Abergwaun Bridge)",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 221,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "SUNDS LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 2,
-          "floorId": 0,
-          "roomDescription": "Flanking the town square on its northern side, this cobblestone lane is home to a small butcher shop and a blacksmith. The simple stone buildings are covered in a layer of soot from the constant burning of coal, needed to forge the tools and weaponry required by the townspeople. To the north, the town gates can be seen in the distance.",
-          "roomTitle": "CRAIGAVON LANE NORTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "66": "Blacksmith",
-            "98": "Butcher"
-          }
-        },
-        {
-          "roomId": 22,
-          "floorId": 0,
-          "roomDescription": "A road departs from the narrow lane headed to the east, lined by statues of lions, with a large granite cliff looming above the end of it. To the west of where you stand, you can see the side entrance to the House of Lanfair. ",
-          "roomTitle": "CRAIGAVON LANE SOUTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 45,
-          "floorId": 0,
-          "roomDescription": "A thick forest envelops your surroundings, obscuring whatever may lie in the distance. Creatures can occasionally be heard rustling through the leaves and branches, but they are not always easily seen.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 87,
-          "floorId": 0,
-          "roomDescription": "A biting, howling wind roars across this hostile mountain terrain, open enough that you can easily make out the town below to the west, though a thick fog often shrouds the area and obscures its view. Winds have been known to occasionally reach hurricane force at this elevation, sometimes scouring the snow off higher slopes and loading it into massive snowdrifts.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 113,
-          "floorId": 0,
-          "roomDescription": "On this large hill, widely spaced pine trees cover the landscape, and the otherwise smooth slope is broken up by a number of horizontal rock outcroppings, some of which contain caves. Grass, shrubs, and bushes with wild berries can be found growing between the pine trees. Small paths heading off the main road can be seen along the route.",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 152,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 257,
-          "floorId": 0,
-          "roomDescription": "Outside the south gate of the city, you notice a small sign pointing east. The sign reads \"Beware, to the east live the most dangerous creatures in these lands. Many have ventured here and many less have returned.\"",
-          "roomTitle": "SOUTH GATE (Exterior)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 334,
-          "floorId": 0,
-          "roomDescription": "From this stone covered beach, Toft Island can be seen in the distance. The freshwater lake draws animals from the surrounding forest, seeking to quench their thirst or hunt for fish.",
-          "roomTitle": "TOFT ISLAND LAKE SHORE",
-          "roomTags": [],
-          "areaNames": [
-            "toft2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 162,
-          "floorId": 0,
-          "roomDescription": "At this section of road, the surroundings bear little evidence of human activity. Being some distance from any town and somewhat isolated, travelers usually work their way along this section of road with a high level of vigilance. The Bloodridge Mountain escarpment can be seen through the trees to the east, and the road appears to run mostly parallel to the mountains.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 153,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 234,
-          "floorId": 0,
-          "roomDescription": "Standing at the southeastern corner of the town, a small door can be seen leading into one of the circular guard towers built into the town wall. Several times a day guards can be seen changing shifts, and occasionally townspeople can be seen bringing food and drink to the guards, as a token of appreciation for the safety they help provide to the town.",
-          "roomTitle": "BREWERY LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 160,
-          "floorId": 0,
-          "roomDescription": "At this section of road, the surroundings bear little evidence of human activity. Being some distance from any town and somewhat isolated, travelers usually work their way along this section of road with a high level of vigilance. The Bloodridge Mountain escarpment can be seen through the trees to the east, and the road appears to run mostly parallel to the mountains. A small stone marker can be seen on the side of the road with XVIII carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 200,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 182,
-          "floorId": 0,
-          "roomDescription": "A small shrine sits on the eastern side of the road, with the flowing stream as a backdrop. Aedylus, a resident of Hammoor, was tragically killed here after being ambushed by a group of ekimmus, while out on a trip to forage for wild mushrooms. Travelers often place small stones atop the shrine, as legends suggest this will bring them good luck while traveling.",
-          "roomTitle": "THE GREAT NORTHERN ROAD (Shrine of Aedylus)",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 236,
-          "floorId": 0,
-          "roomDescription": "This wide alley is part of the main north to south route in the town, continuing onward to The Northway to the north and connecting to the Town Square, and southward to the South Gate.",
-          "roomTitle": "SOUTH GATE ALLEY",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 229,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "SUNDS LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 112,
-          "floorId": 0,
-          "roomDescription": "Arriving at the crest of a large hill, a large body of water can be seen in the distance to the west. A small island sits some distance out into the water, and you can barely make out several man made structures built there. To the east, the hill descends gradually, with thick vegetation obscuring the bottom.",
-          "roomTitle": "EDGAR\u0027S WOODS (Toft Island Road)",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 56,
-          "floorId": 0,
-          "roomDescription": "Vegetables, herbs and spices at various stages of growth dominate this small community garden. A stone, horseshoe shaped pathway leads through the garden to provide access. Two stone benches are placed along the pathway, providing a relaxing place to rest.",
-          "roomTitle": "STORMARN GARDEN",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 105,
-          "floorId": 0,
-          "roomDescription": "Marshes and swamps line this pathway through the forest, with care needed to avoid stepping into deep mud. Ferns and mushrooms grow abundantly, and the chorus of thousands of frogs can be heard in the surrounding area.",
-          "roomTitle": "EDGAR\u0027S WOODS",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 128,
-          "floorId": 0,
-          "roomDescription": "Arriving at the main ferry dock which provides access to Toft Island, you see a large sign detailing the ferry schedule and ticket prices. Two ferries typically run between here and the island, which are relied upon to carry both goods and passengers.",
-          "roomTitle": "TOFT ISLAND FERRY DOCK",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 159,
-          "floorId": 0,
-          "roomDescription": "At this section of road, the surroundings bear little evidence of human activity. Being some distance from any town and somewhat isolated, travelers usually work their way along this section of road with a high level of vigilance. The Bloodridge Mountain escarpment can be seen through the trees to the east, and the road appears to run mostly parallel to the mountains.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 158,
-          "floorId": 0,
-          "roomDescription": "At this section of road, the surroundings bear little evidence of human activity. Being some distance from any town and somewhat isolated, travelers usually work their way along this section of road with a high level of vigilance. The Bloodridge Mountain escarpment can be seen through the trees to the east, and the road appears to run mostly parallel to the mountains.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 132,
-          "floorId": 0,
-          "roomDescription": "A steep staircase descends this otherwise impassible section of the trail, with Bloodridge Mountain Pass only slightly further uphill. Below the staircase, Segeberg Castle can be seen some distance away, long abandoned by most of its inhabitants. A small stone marker on the side of the road is carved with XXX.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 218,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "WYK LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 26,
-          "floorId": 0,
-          "roomDescription": "A stone archway marks the entrance to the city. Two guards armed with pikes stand at either side of the gate. Behind them are thick stone walls made of granite. The guards vigilantly observe the countryside past the city walls, ready to defend the town against the dangers which lie outside. Above, you notice two guard towers on either side of the gate, with archers positioned in each.",
-          "roomTitle": "NORTH GATE",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 21,
-          "floorId": 0,
-          "roomDescription": "Outside the town square, you find yourself on a quiet, one carriage width lane. On the western side of the street sits the House of Lanfair, with marble columns at its corners. The House extends southward, well beyond this area, via a second story bridge connecting to its southern wing. A wide passageway to the west and under the bridge leads to the main entrance of the house on the right, and beyond the entrance a parking area for carriages can be seen.",
-          "roomTitle": "CRAIGAVON LANE SOUTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "57": "entrance"
-          }
-        },
-        {
-          "roomId": 215,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "WYK LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 157,
-          "floorId": 0,
-          "roomDescription": "At this section of road, the surroundings bear little evidence of human activity. Being some distance from any town and somewhat isolated, travelers usually work their way along this section of road with a high level of vigilance. The Bloodridge Mountain escarpment can be seen through the trees to the east, and the road appears to run mostly parallel to the mountains. A small stone marker can be seen on the side of the road with XV carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 166,
-          "floorId": 0,
-          "roomDescription": "Bisecting deep wilderness, the road here was built alongside a wide stream flowing from high in the Bloodridge Mountains, as this provided one of the only relatively flat places to construct it. The sound of rushing water can be heard all along the road, fueled by melting glaciers high above. A small stone marker can be seen on the side of the road with XXIV carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 123,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "TOFT ISLAND ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 79,
-          "floorId": 0,
-          "roomDescription": "This treacherous, steep road winds back and forth along a dangerous mountainside. Compared to the valley, the temperature feels significantly colder here. You notice caves dotting the mountainside, some of which appear to be inhabited by creatures.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 86,
-          "floorId": 0,
-          "roomDescription": "The higher elevations of the western slopes of Bloodridge Mountain Road receive frequent snowfalls,and a coating of old snow covers the surrounding terrain. Along this steepsection of road, rockfalls are common, which can often make the road impassibleuntil cleared. A small stone marker on the side of the road is carved with XV.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 147,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 214,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "WYK LANE (The Northway Intersection)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 192,
-          "floorId": 0,
-          "roomDescription": "In the immediate vicinity of the Town of Hammoor, the road here is paved with smooth stones, many taken from riverbeds. The town\u0027s main gate and barbican can be seen some distance to the north, sitting immediately next to the sheer cliffs of the Bloodridge Mountain escarpment. A small stone marker can be seen on the side of the road with XLVIII carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 235,
-          "floorId": 0,
-          "roomDescription": "At the very southern end of Craigavon Lane, the town wall can be seen to the south where the lane meets Brewery Lane. A large building sits on the eastern side of the street, used to store a supply of grains and food for the town that could sustain the town for months, in the event of a siege. The granary walls are covered in a thick coat of plaster, in an effort to seal the walls and prevent the incursion of mice.",
-          "roomTitle": "CRAIGAVON LANE SOUTH",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 38,
-          "floorId": 0,
-          "roomDescription": "Halfway down Victory Road, you notice a small laneway leading north, cutting between the row houses which otherwise dominate the area. An area provided for keeping horses sits just to the right side of the laneway, along with a trough filled with water.",
-          "roomTitle": "VICTORY ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 106,
-          "floorId": 0,
-          "roomDescription": "Marshes and swamps line this pathway through the forest, with care needed to avoid stepping into deep mud. Ferns and mushrooms grow abundantly, and the chorus of thousands of frogs can be heard in the surrounding area.",
-          "roomTitle": "EDGAR\u0027S WOODS",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 225,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "PARADOX CRESCENT",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 164,
-          "floorId": 0,
-          "roomDescription": "Bisecting deep wilderness, the road here was built alongside a wide stream flowing from high in the Bloodridge Mountains, as this provided one of the only relatively flat places to construct it. The sound of rushing water can be heard all along the road, fueled by melting glaciers high above.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 196,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 237,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "SOUTH GATE (Interior)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "256": "gate"
-          }
-        },
-        {
-          "roomId": 230,
-          "floorId": 0,
-          "roomDescription": "A fairly wide, somewhat industrial thoroughfare, many tradespeople and those of the merchant class operate businesses along this wide lane, which offers close access to the South Gate, and is anchored by the town brewery. Large, simple stone structures line the road, mainly used as warehouses, though some are used to house animals and some are even used for manufacturing various goods. Double wooden doors, at least twice as high as the height of an average person, mark the entrance to these mostly identical looking buildings.",
-          "roomTitle": "BREWERY LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 42,
-          "floorId": 0,
-          "roomDescription": "Set only a short distance from Victory Road, you see a large mansion partially hidden behind eight foot high hedges. Looking through the wrought iron front gate, a doorway can be seen flanked by massive stone columns. A small sign affixed to the gate reads \"HOUSE OF FIRTH - MEMBERS ONLY\". Below the sign, a heavy lock secures the gate.",
-          "roomTitle": "HOUSE OF FIRTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {
-            "69": "House"
-          }
-        },
-        {
-          "roomId": 217,
-          "floorId": 0,
-          "roomDescription": "This cul-de-sac faces a large cliff below the Manor House. Several carts can be seen sitting parked here, the majority of which are owned by local merchants and used to move their wares around town. A pile of cobblestones sits nearly stacked in a corner, waiting to be used for repairing the town\u0027s roads.",
-          "roomTitle": "WYK COURT",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 223,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "PARADOX CRESCENT",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 191,
-          "floorId": 0,
-          "roomDescription": "In the immediate vicinity of the Town of Hammoor, the road here is paved with smooth stones, many taken from riverbeds. The town\u0027s main gate and barbican can be seen some distance to the north, sitting immediately next to the sheer cliffs of the Bloodridge Mountain escarpment.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 174,
-          "floorId": 0,
-          "roomDescription": "With the road passing through a boggy landscape, dead trees can be seen everywhere, having rotten at the roots. An unpleasant dank, musty smell from rotting wood hovers over the area. Since the road provides a relatively dry and smooth surface to travel along, it is not only used by travelers, but nearly every beast of the forest as well.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 233,
-          "floorId": 0,
-          "roomDescription": "A fairly wide, somewhat industrial thoroughfare, many tradespeople and those of the merchant class operate businesses along this wide lane, which offers close access to the South Gate, and is anchored by the town brewery. Large, simple stone structures line the road, mainly used as warehouses, though some are used to house animals and some are even used for manufacturing various goods. Double wooden doors, at least twice as high as the height of an average person, mark the entrance to these mostly identical looking buildings.",
-          "roomTitle": "BREWERY LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 202,
-          "floorId": 0,
-          "roomDescription": "The air is thick with humidity in this swamp, as you move through it. Insects abound, it is unpleasant to linger here, though the flora grows abundantly.",
-          "roomTitle": "SHULDHAM SWAMP",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 151,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north. A small stone marker can be seen on the side of the road with IX carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 48,
-          "floorId": 0,
-          "roomDescription": "The small lane is flanked by two small homes and a large stablehouse, shared by both the Manor House and the House of Lanfair. Fifteen foot high wooden doors serve as the entrance to the stablehouse, where horses are kept both for the Manor, and for guests of the House of Lanfair when there is no longer space in the adjacent alleyway.",
-          "roomTitle": "CRAIGAVON LANE SOUTH",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 170,
-          "floorId": 0,
-          "roomDescription": "Being relatively close to the foothills, the slight inclination of the terrain has caused the neighboring stream to form rapids. As the violently churning water smashes into rocks, a fine mist shrouds the area, and many varieties of mushrooms can be seen growing by the roadside, providing an attractive opportunity to forage.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north3_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 220,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "WYK LANE",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 149,
-          "floorId": 0,
-          "roomDescription": "The wide road continues to wind through the forest, approaching the town to the south, and veering toward the Bloodridge Mountain Range escarpment for those traveling north. Though the most dangerous creatures previously inhabiting these woods have long been driven off, untamed lands lie to the far north.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 94,
-          "floorId": 0,
-          "roomDescription": "A path thick with ice makes travel extremely difficult at this high elevation, with deep snowpack seen on all sides. Maintaining your footing is difficult on the ice, but leaving the road would be even more challenging, as the unpacked snow causes one to sink waist deep or more with each step. The only vegetation growing here is in the form of stunted trees, many of which have branches on only one side from being constantly battered by high winds.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 110,
-          "floorId": 0,
-          "roomDescription": "A constant slope rises toward the west, gradually rising in elevation above the swamps below. Toward the east, the forest appears much thicker, and the sound of frogs can be heard.",
-          "roomTitle": "EDGAR\u0027S WOODS (Toft Island Road)",
-          "roomTags": [],
-          "areaNames": [
-            "toft1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 83,
-          "floorId": 0,
-          "roomDescription": "This treacherous, steep road winds back and forth along a dangerous mountainside. Compared to the valley, the temperature feels significantly colder here. You notice caves dotting the mountainside, some of which appear to be inhabited by creatures. A small stone marker on the side of the road is carved with XII.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 93,
-          "floorId": 0,
-          "roomDescription": "A path thick with ice makes travel extremely difficult at this high elevation, with deep snowpack seen on all sides. Maintaining your footing is difficult on the ice, but leaving the road would be even more challenging, as the unpacked snow causes one to sink waist deep or more with each step. The only vegetation growing here is in the form of stunted trees, many of which have branches on only one side from being constantly battered by high winds.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 189,
-          "floorId": 0,
-          "roomDescription": "In the immediate vicinity of the Town of Hammoor, the road here is paved with smooth stones, many taken from riverbeds. The town\u0027s main gate and barbican can be seen some distance to the north, sitting immediately next to the sheer cliffs of the Bloodridge Mountain escarpment. A small stone marker can be seen on the side of the road with XLV carved into it.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 46,
-          "floorId": 0,
-          "roomDescription": "Traveling down the Great Northern Road, you come to a stone arch bridge wide enough for one carriage to pass. The Abergwaun Stream runs underneath, providing excellent fishing opportunities. Several small paths lead downward toward the stream, evidence of those who have fished here throughout the past.",
-          "roomTitle": "THE GREAT NORTHERN ROAD (Abergwaun Bridge)",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 50,
-          "floorId": 0,
-          "roomDescription": "A narrow pathway continues through the thick woods, and footprints are visible in the mud.",
-          "roomTitle": "EDGAR\u0027S WOODS",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 82,
-          "floorId": 0,
-          "roomDescription": "This treacherous, steep road winds back and forth along a dangerous mountainside. Compared to the valley, the temperature feels significantly colder here. You notice caves dotting the mountainside, some of which appear to be inhabited by creatures.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 181,
-          "floorId": 0,
-          "roomDescription": "",
-          "roomTitle": "\u003cPLACEHOLDER\u003e",
-          "roomTags": [],
-          "areaNames": [
-            "north4_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 131,
-          "floorId": 0,
-          "roomDescription": "Near the Bloodridge Mountain pass, the arid eastern side of the range, whilefrigid, holds far less snow than the western slopes. Stunted pines grow in thesurrounding area, never growing more than a few feet due to being constantlybattered by heavy winds. A steep trail winds downward, while immediately above,the top of the pass is visible.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 52,
-          "floorId": 0,
-          "roomDescription": "In the thick forest you find a large hunting clubhouse crafted mostly from wood. Pelts are hung to dry from racks constructed outside, and a stone pathway leads to the front door. A fire ring can be seen in the woods past the house, used for ceremonial bonfires.",
-          "roomTitle": "HAUGSEITH HOUSE",
-          "roomTags": [],
-          "areaNames": [
-            "north2_zone"
-          ],
-          "enterExitNames": {
-            "67": "House"
-          }
-        },
-        {
-          "roomId": 85,
-          "floorId": 0,
-          "roomDescription": "The higher elevations of the western slopes of Bloodridge Mountain Road receive frequent snowfalls,and a coating of old snow covers the surrounding terrain. Along this steepsection of road, rockfalls are common, which can often make the road impassibleuntil cleared.",
-          "roomTitle": "BLOODRIDGE MOUNTAIN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "bloodridge1_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 43,
-          "floorId": 0,
-          "roomDescription": "A thick forest envelops your surroundings, obscuring whatever may lie in the distance. Creatures can occasionally be heard rustling through the leaves and branches, but they are not always easily seen.",
-          "roomTitle": "THE GREAT NORTHERN ROAD",
-          "roomTags": [],
-          "areaNames": [
-            "north1_zone"
-          ],
-          "enterExitNames": {}
-        }
-      ]
-    },
-    {
-      "name": "74d7b872-55fe-4b5e-afc5-728897afdb1a",
-      "id": 20,
-      "rawMatrixCsv": ",,,208,,,,,,,,,,,,,,\n,,,207,,,,,,,,,,,,,,\n240,239,238,206,,,,,,,,,,,,,,\n,,,205,,,,,,,,,,,,,,\n,,,204,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 238,
-          "floorId": 20,
-          "roomDescription": "Named for the ancient forge here, Forge Road connects the Town of Hammoor to the former Royal Hunting Grounds just to the west. The forge continues to be used as a Blacksmith shop, serving the needs of the townspeople and travelers.",
-          "roomTitle": "FORGE ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "253": "Blacksmith"
-          }
-        },
-        {
-          "roomId": 239,
-          "floorId": 20,
-          "roomDescription": "Named for the ancient forge located just to the east, Forge Road connects the Town of Hammoor to the former Royal Hunting Grounds just to the west. The forge continues to be used as a Blacksmith shop, serving the needs of the townspeople and travelers.",
-          "roomTitle": "FORGE ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 205,
-          "floorId": 20,
-          "roomDescription": "Taking the name from the fortified stone barbican which protects the main entrance to the city, this thoroughfare splits the town of Hammoor in half. Some of the town\u0027s merchants have chosen to open their shops along this road, as it is conveniently located for shipping and receiving goods that have traveled or will travel up the Great Northern Road. A bank can be seen on the eastern side of the street, constructed from exceptionally massive stones.",
-          "roomTitle": "BARBICAN ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "209": "Bank"
-          }
-        },
-        {
-          "roomId": 206,
-          "floorId": 20,
-          "roomDescription": "Taking the name from the fortified stone barbican which protects the main entrance to the city, this thoroughfare splits the town of Hammoor in half. Some of the town\u0027s merchants have chosen to open their shops along this road, as it is conveniently located for shipping and receiving goods that have traveled or will travel up the Great Northern Road.",
-          "roomTitle": "BARBICAN ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 208,
-          "floorId": 20,
-          "roomDescription": "Taking the name from the fortified stone barbican which protects the main entrance to the city, this thoroughfare splits the town of Hammoor in half. Some of the town\u0027s merchants have chosen to open their shops along this road, as it is conveniently located for shipping and receiving goods that have traveled or will travel up the Great Northern Road.",
-          "roomTitle": "BARBICAN ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [
-            "newbie_zone"
-          ],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 207,
-          "floorId": 20,
-          "roomDescription": "Taking the name from the fortified stone barbican which protects the main entrance to the city, this thoroughfare splits the town of Hammoor in half. Some of the town\u0027s merchants have chosen to open their shops along this road, as it is conveniently located for shipping and receiving goods that have traveled or will travel up the Great Northern Road.",
-          "roomTitle": "BARBICAN ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {}
-        },
-        {
-          "roomId": 204,
-          "floorId": 20,
-          "roomDescription": "",
-          "roomTitle": "TOWN OF HAMMOOR (Main Gate Interior)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "193": "Leave"
-          }
-        },
-        {
-          "roomId": 240,
-          "floorId": 20,
-          "roomDescription": "Having reached the end of Forge Road, a narrow gate can be seen exiting the town here, leading to the hunting grounds west of town.",
-          "roomTitle": "FORGE ROAD (Town of Hammoor)",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "241": "gate"
-          }
-        }
-      ]
-    },
-    {
-      "name": "c2d1c33d-5620-444a-97a5-2cea6f298980",
-      "id": 21,
-      "rawMatrixCsv": "209,,,,,,,,,,,,,,\n",
-      "roomModels": [
-        {
-          "roomId": 209,
-          "floorId": 21,
-          "roomDescription": " Built similarly to other banks, this imposing structure features columns on two sides of the room, with a large counter at the end staffed by a banker. A vault can be seen behind the banker, safeguarding the wealth of the townspeople.",
-          "roomTitle": "HAMMOOR TOWN BANK",
-          "roomTags": [],
-          "areaNames": [],
-          "enterExitNames": {
-            "205": "Leave"
-          }
-        }
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/world/npcs/allah.json b/world/npcs/allah.json
deleted file mode 100755
index 2d0ffeb584ac1756002b62a015044d1e7246d0ec..0000000000000000000000000000000000000000
--- a/world/npcs/allah.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "allah",
-  "colorName": "\u001B[1m\u001B[35mallah\u001B[0m",
-  "dieMessage": "ALLAH U AHKBAR! \u001B[1m\u001B[35mallah\u001B[0m has died and promises to seek vengeance.",
-  "loot": {
-    "lootGoldMin": 300000,
-    "lootGoldMax": 600000,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "tisland3_zone",
-    "tisland4_zone"
-  ],
-  "stats": {
-    "agile": 400,
-    "aim": 400,
-    "armorRating": 1440,
-    "currentHealth": 300000,
-    "currentMana": 300000,
-    "experience": 250000,
-    "maxHealth": 300000,
-    "maxMana": 300000,
-    "meleSkill": 2400,
-    "numberOfWeaponRolls": 15,
-    "strength": 4000,
-    "weaponRatingMax": 4000,
-    "weaponRatingMin": 2300,
-    "willPower": 4000
-  },
-  "spawnAreas": {
-    "tisland10_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "allah"
-  ]
-}
diff --git a/world/npcs/alpinetiger.json b/world/npcs/alpinetiger.json
deleted file mode 100644
index 51c301221a8001cc87fab8f9c98cd36b2ea553e9..0000000000000000000000000000000000000000
--- a/world/npcs/alpinetiger.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "alpine tiger",
-  "colorName": "alpine \u001B[1m\u001B[35mtiger\u001B[0m",
-  "dieMessage": "the alpine \u001B[1m\u001B[35mtiger\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 31000000,
-    "lootGoldMax": 36000000,
-    "lootItems": [76]
-  },
-  "roamAreas": [
-    "bloodridge12_zone",
-    "bloodridge13_zone"
-  ],
-  "stats": {
-    "agile": 10000,
-    "aim": 12000,
-    "armorRating": 41000,
-    "currentHealth": 2000000,
-    "currentMana": 1200000,
-    "experience": 16000000,
-    "maxHealth": 2500000,
-    "maxMana": 800000,
-    "meleSkill": 110000,
-    "numberOfWeaponRolls": 20,
-    "strength": 110000,
-    "weaponRatingMax": 150000,
-    "weaponRatingMin": 70000,
-    "willPower": 30000
-  },
-  "spawnAreas": {
-    "bloodridge12_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge13_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "alpine tiger",
-    "a",
-    "t",
-    "alpine",
-    "tiger"
-  ]
-}
diff --git a/world/npcs/alpineyeti.json b/world/npcs/alpineyeti.json
deleted file mode 100644
index aa275c731a7bedbcc7bac45365a897e127291edc..0000000000000000000000000000000000000000
--- a/world/npcs/alpineyeti.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "alpine yeti",
-  "colorName": "alpine \u001B[1m\u001B[35myeti\u001B[0m",
-  "dieMessage": "alpine yeti \u001B[1m\u001B[35mbiggers\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 35000,
-    "lootGoldMax": 50000,
-    "lootItems": [55, 56]
-  },
-  "roamAreas": [
-    "bloodridge8_zone",
-    "bloodridge9_zone"
-  ],
-  "stats": {
-    "agile": 70,
-    "aim": 70,
-    "armorRating": 500,
-    "currentHealth": 65000,
-    "currentMana": 100,
-    "experience": 90000,
-    "maxHealth": 600,
-    "maxMana": 100,
-    "meleSkill": 400,
-    "numberOfWeaponRolls": 5,
-    "strength": 800,
-    "weaponRatingMax": 700,
-    "weaponRatingMin": 500,
-    "willPower": 16
-  },
-  "spawnAreas": {
-    "bloodridge8_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 3
-    }, 
-    "bloodridge9_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    } 
-  },
-  "validTriggers": [
-    "alpine yeti",
-    "a",
-    "alpine",
-    "y",
-    "yeti"
-  ]
-}
diff --git a/world/npcs/amarok.json b/world/npcs/amarok.json
deleted file mode 100644
index ee49226c9cfda8759463282d9367bd14f0c35151..0000000000000000000000000000000000000000
--- a/world/npcs/amarok.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "name": "amarok",
-  "colorName": "\u001B[1m\u001B[35mamarok\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mamarok\u001B[0m collapses to its death and its spirit vanishes into the shadows.",
-  "loot": {
-    "lootGoldMin": 500000,
-    "lootGoldMax": 800000,
-    "lootItems": [57]
-  },
-  "roamAreas": [
-    "bloodridge10_zone",
-    "bloodridge11_zone"
-  ],
-  "stats": {
-    "agile": 500,
-    "aim": 500,
-    "armorRating": 1840,
-    "currentHealth": 400000,
-    "currentMana": 400000,
-    "experience": 400000,
-    "maxHealth": 400000,
-    "maxMana": 400000,
-    "meleSkill": 3000,
-    "numberOfWeaponRolls": 15,
-    "strength": 6000,
-    "weaponRatingMax": 6000,
-    "weaponRatingMin": 4300,
-    "willPower": 4000
-  },
-  "spawnAreas": {
-    "bloodridge10_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "amarok",
-    "a"
-  ]
-}
diff --git a/world/npcs/ancientberserker.json b/world/npcs/ancientberserker.json
deleted file mode 100644
index 88ac345fd02c409c812f7c4de22715953586e9e6..0000000000000000000000000000000000000000
--- a/world/npcs/ancientberserker.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "ancient berserker",
-  "colorName": "ancient \u001B[1m\u001B[35mberserker\u001B[0m",
-  "dieMessage": "the ancient \u001B[1m\u001B[35mberserker\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 42000000,
-    "lootGoldMax": 52000000,
-    "lootItems": [80]
-  },
-  "roamAreas": [
-    "bloodridge14_zone",
-    "bloodridge15_zone"
-  ],
-  "stats": {
-    "agile": 13000,
-    "aim": 16000,
-    "armorRating": 82000,
-    "currentHealth": 4000000,
-    "currentMana": 2400000,
-    "experience": 24000000,
-    "maxHealth": 5000000,
-    "maxMana": 1600000,
-    "meleSkill": 140000,
-    "numberOfWeaponRolls": 20,
-    "strength": 160000,
-    "weaponRatingMax": 180000,
-    "weaponRatingMin": 80000,
-    "willPower": 80000
-  },
-  "spawnAreas": {
-    "bloodridge14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "ancient",
-    "a",
-    "b",
-    "berserker",
-    "ancient berserker"
-  ]
-}
diff --git a/world/npcs/apocalypticdruid.json b/world/npcs/apocalypticdruid.json
deleted file mode 100644
index a3cec740bef1c6170affcec6dbc08edef062137d..0000000000000000000000000000000000000000
--- a/world/npcs/apocalypticdruid.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "apocalyptic druid",
-  "colorName": "apocalyptic \u001B[1m\u001B[35mdruid\u001B[0m",
-  "dieMessage": "the apocalyptic \u001B[1m\u001B[35mdruid\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 225000000,
-    "lootGoldMax": 300000000,
-    "lootItems": [85]
-  },
-  "roamAreas": [
-    "tisland8_zone",
-    "tisland9_zone"
-  ],
-  "stats": {
-    "agile": 63000,
-    "aim": 81000,
-    "armorRating": 380000,
-    "currentHealth": 15000000,
-    "currentMana": 9000000,
-    "experience": 120000000,
-    "maxHealth": 18000000,
-    "maxMana": 7200000,
-    "meleSkill": 630000,
-    "numberOfWeaponRolls": 50,
-    "strength": 1000000,
-    "weaponRatingMax": 1050000,
-    "weaponRatingMin": 930000,
-    "willPower": 400000
-  },
-  "spawnAreas": {
-    "tisland8_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "tisland9_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "apocalyptic druid",
-    "a",
-    "d",
-    "apocalyptic",
-    "druid"
-  ]
-}
diff --git a/world/npcs/ashwraith.json b/world/npcs/ashwraith.json
deleted file mode 100644
index 29915cb8e066468cf4a67e457097eae290558b30..0000000000000000000000000000000000000000
--- a/world/npcs/ashwraith.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "ash wraith",
-  "colorName": "ash \u001B[1m\u001B[35mwraith\u001B[0m",
-  "dieMessage": "the ash \u001B[1m\u001B[35mwraith\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 73000000000,
-    "lootGoldMax": 94000000000,
-    "lootItems": [150]
-  },
-  "roamAreas": [
-    "bloodridge18_zone",
-    "bloodridge19_zone"
-  ],
-  "stats": {
-    "agile": 1400000,
-    "aim": 1302000,
-    "armorRating": 63000000,
-    "currentHealth": 3300000000,
-    "currentMana": 1900000000,
-    "experience": 17000000000,
-    "maxHealth": 3300000000,
-    "maxMana": 1100000000,
-    "meleSkill": 144000000,
-    "numberOfWeaponRolls": 5000,
-    "strength": 144000000,
-    "weaponRatingMax": 222000000,
-    "weaponRatingMin": 190000000,
-    "willPower": 142000000
-  },
-  "spawnAreas": {
-    "bloodridge18_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    },
-    "bloodridge19_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }
-  },
-  "validTriggers": [
-    "ash wraith",
-    "ash",
-    "wraith",
-    "a",
-    "w"
-  ]
-}
diff --git a/world/npcs/banshee.json b/world/npcs/banshee.json
deleted file mode 100644
index 6df2d74a5efe8adcb4e2f6761ab1a5a11d03259c..0000000000000000000000000000000000000000
--- a/world/npcs/banshee.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "banshee",
-  "colorName": "\u001B[1m\u001B[35mbanshee\u001B[0m",
-  "dieMessage": "a \u001B[1m\u001B[35mbanshee\u001B[0m lets out a blood curdling scream as it collapses and dies.",
-  "loot": {
-    "lootGoldMin": 600000,
-    "lootGoldMax": 920000,
-    "lootItems": [58]
-  },
-  "roamAreas": [
-    "south2_zone",
-    "south3_zone"
-  ],
-  "stats": {
-    "agile": 700,
-    "aim": 700,
-    "armorRating": 3000,
-    "currentHealth": 300000,
-    "currentMana": 300000,
-    "experience": 250000,
-    "maxHealth": 300000,
-    "maxMana": 300000,
-    "meleSkill": 4000,
-    "numberOfWeaponRolls": 15,
-    "strength": 5300,
-    "weaponRatingMax": 6300,
-    "weaponRatingMin": 2300,
-    "willPower": 4000
-  },
-  "spawnAreas": {
-    "south2_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 4
-    }, 
-    "south3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }  
-  },
-  "validTriggers": [
-    "banshee",
-    "b"
-  ]
-}
diff --git a/world/npcs/basilisk.json b/world/npcs/basilisk.json
deleted file mode 100644
index 1d4d6079686333e9f205707fce4af2c95f11a4aa..0000000000000000000000000000000000000000
--- a/world/npcs/basilisk.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "basilisk",
-  "colorName": "\u001B[1m\u001B[35mbasilisk\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mbasilisk\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 800000000,
-    "lootGoldMax": 1000000000,
-    "lootItems": [108]
-  },
-  "roamAreas": [
-    "north14_zone",
-    "north15_zone"
-  ],
-  "stats": {
-    "agile": 180000,
-    "aim": 178000,
-    "armorRating": 750000,
-    "currentHealth": 34000000,
-    "currentMana": 22000000,
-    "experience": 220000000,
-    "maxHealth": 34000000,
-    "maxMana": 12000000,
-    "meleSkill": 1400000,
-    "numberOfWeaponRolls": 80,
-    "strength": 1350000,
-    "weaponRatingMax": 2200000,
-    "weaponRatingMin": 1300000,
-    "willPower": 1100000
-  },
-  "spawnAreas": {
-    "north14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "north15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "basilisk",
-    "b"
-  ]
-}
diff --git a/world/npcs/bergorc.json b/world/npcs/bergorc.json
deleted file mode 100755
index a098500515722de042956d41e2d365382fc973f0..0000000000000000000000000000000000000000
--- a/world/npcs/bergorc.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-  "name": "berg orc",
-  "colorName": "berg \u001B[1m\u001B[35morc\u001B[0m",
-  "dieMessage": "a berg \u001B[1m\u001B[35morc\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 6,
-    "lootGoldMax": 20,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "bloodridge1_zone"
-  ],
-  "stats": {
-    "agile": 1,
-    "aim": 1,
-    "armorRating": 8,
-    "currentHealth": 230,
-    "currentMana": 100,
-    "experience": 250,
-    "maxHealth": 230,
-    "maxMana": 100,
-    "meleSkill": 6,
-    "numberOfWeaponRolls": 1,
-    "strength": 11,
-    "weaponRatingMax": 13,
-    "weaponRatingMin": 10,
-    "willPower": 1
-  },
-  "spawnAreas": {
-    "bloodridge1_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 12
-    }
-  },
-  "validTriggers": [
-    "b",
-    "berg orc",
-    "orc",
-    "o"
-  ]
-}
diff --git a/world/npcs/billcosby.json b/world/npcs/billcosby.json
deleted file mode 100644
index e00081314d019f2a5f0f22248319e9ccfef1b508..0000000000000000000000000000000000000000
--- a/world/npcs/billcosby.json
+++ /dev/null
@@ -1,130 +0,0 @@
-{
-  "name": "bill cosby",
-  "colorName": "bill \u001B[1m\u001B[35mcosby\u001B[0m",
-  "dieMessage": "bill \u001B[1m\u001B[35mcosby\u001B[0m collapses and scatters \u001B[1m\u001B[31mdrugs\u001B[0m all over the ground",
-  "loot": {
-    "lootGoldMin": 120,
-    "lootGoldMax": 180,
-    "lootItems": [2, 28, 41, 42, 46, 54]
-  },
-  "roamAreas": [
-    "lobby",
-    "newbie_zone",
-    "house_zone",
-    "fancyhouse_zone",
-    "north1_zone",
-    "north2_zone",
-    "north3_zone",
-    "north4_zone",
-    "north5_zone",
-    "north6_zone",
-    "north7_zone",
-    "north8_zone",
-    "north9_zone",
-    "north10_zone",
-    "north11_zone",
-    "north12_zone",
-    "north13_zone",
-    "north14_zone",
-    "north15_zone",
-    "bloodridge1_zone",
-    "bloodridge2_zone",
-    "bloodridge3_zone",
-    "bloodridge4_zone",
-    "bloodridge5_zone",
-    "bloodridge6_zone",
-    "bloodridge7_zone",
-    "bloodridge8_zone",
-    "bloodridge9_zone",
-    "bloodridge10_zone",
-    "bloodridge11_zone",
-    "bloodridge12_zone",
-    "bloodridge13_zone",
-    "bloodridge14_zone",
-    "bloodridge15_zone",
-    "bloodridge11_zone",
-    "bloodridge12_zone",
-    "bloodridge13_zone",
-    "bloodridge14_zone",
-    "bloodridge15_zone",
-    "western1_zone",
-    "western2_zone",
-    "western3_zone",
-    "western4_zone",
-    "western5_zone",
-    "western6_zone",
-    "western7_zone",
-    "western8_zone",
-    "western9_zone",
-    "western10_zone",
-    "toft1_zone",
-    "toft2_zone",
-    "toft3_zone",
-    "toft4_zone",
-    "toft5_zone",
-    "tisland1_zone",
-    "tisland2_zone",
-    "tisland3_zone",
-    "tisland4_zone",
-    "tisland5_zone",
-    "tisland6_zone",
-    "tisland7_zone",
-    "tisland8_zone",
-    "tisland9_zone",
-    "tisland10_zone",
-    "south1_zone",
-    "south2_zone",
-    "south3_zone",
-    "south4_zone",
-    "south5_zone",
-    "south6_zone",
-    "south7_zone",
-    "south8_zone",
-    "south9_zone",
-    "south10_zone",
-    "radio_room"
-  ],
-  "stats": {
-    "agile": 14,
-    "aim": 14,
-    "armorRating": 25,
-    "currentHealth": 1200,
-    "currentMana": 300,
-    "experience": 2600,
-    "maxHealth": 1200,
-    "maxMana": 100,
-    "meleSkill": 19,
-    "numberOfWeaponRolls": 1,
-    "strength": 70,
-    "weaponRatingMax": 60,
-    "weaponRatingMin": 35,
-    "willPower": 35
-  },
-  "spawnAreas": {
-    "western9_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge10_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    },
-    "tisland5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1    
-    }
-  },
-  "validTriggers": [
-    "bill",
-    "cosby",
-    "b",
-    "c",
-    "bill cosby"
-  ]
-}
diff --git a/world/npcs/blackhabrok.json b/world/npcs/blackhabrok.json
deleted file mode 100644
index c705afa459e7df0958c8d0e14186205b594c663f..0000000000000000000000000000000000000000
--- a/world/npcs/blackhabrok.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "black habrok",
-  "colorName": "black \u001B[1m\u001B[35mhabrok\u001B[0m",
-  "dieMessage": "the black \u001B[1m\u001B[35mhabrok\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 11000000,
-    "lootGoldMax": 16000000,
-    "lootItems": [72]
-  },
-  "roamAreas": [
-    "western3_zone",
-    "western4_zone"
-  ],
-  "stats": {
-    "agile": 3000,
-    "aim": 4000,
-    "armorRating": 23000,
-    "currentHealth": 2000000,
-    "currentMana": 1200000,
-    "experience": 8000000,
-    "maxHealth": 1000000,
-    "maxMana": 800000,
-    "meleSkill": 40000,
-    "numberOfWeaponRolls": 15,
-    "strength": 40000,
-    "weaponRatingMax": 47000,
-    "weaponRatingMin": 29000,
-    "willPower": 16000
-  },
-  "spawnAreas": {
-    "western3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "western4_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "black habrok",
-    "b",
-    "h",
-    "black",
-    "habrok"
-  ]
-}
diff --git a/world/npcs/blackhoodedwizard.json b/world/npcs/blackhoodedwizard.json
deleted file mode 100755
index 7f7239ca1b41fc73ab678e53e7838b423344a7e5..0000000000000000000000000000000000000000
--- a/world/npcs/blackhoodedwizard.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "black-hooded wizard",
-  "colorName": "black-hooded \u001B[1m\u001B[35mwizard\u001B[0m",
-  "dieMessage": "a black-hooded \u001B[1m\u001B[35mwizard\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 55,
-    "lootGoldMax": 74,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "tisland4_zone",
-    "tisland5_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 6,
-    "armorRating": 17,
-    "currentHealth": 650,
-    "currentMana": 100,
-    "experience": 1500,
-    "maxHealth": 650,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 35,
-    "weaponRatingMax": 32,
-    "weaponRatingMin": 22,
-    "willPower": 7
-  },
-  "spawnAreas": {
-    "tisland4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "tisland5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "black-hooded",
-    "b",
-    "black-hooded wizard",
-    "wizard",
-    "w"
-  ]
-}
diff --git a/world/npcs/bloodvulture.json b/world/npcs/bloodvulture.json
deleted file mode 100644
index 02434f0aba399d3b96ba7ba261427f246d979d12..0000000000000000000000000000000000000000
--- a/world/npcs/bloodvulture.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "blood vulture",
-  "colorName": "blood \u001B[1m\u001B[35mvulture\u001B[0m",
-  "dieMessage": "the blood \u001B[1m\u001B[35mvulture\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 62000000,
-    "lootGoldMax": 72000000,
-    "lootItems": [78]
-  },
-  "roamAreas": [
-    "bloodridge14_zone",
-    "bloodridge15_zone"
-  ],
-  "stats": {
-    "agile": 20000,
-    "aim": 24000,
-    "armorRating": 82000,
-    "currentHealth": 4000000,
-    "currentMana": 2400000,
-    "experience": 32000000,
-    "maxHealth": 5000000,
-    "maxMana": 1600000,
-    "meleSkill": 220000,
-    "numberOfWeaponRolls": 20,
-    "strength": 220000,
-    "weaponRatingMax": 300000,
-    "weaponRatingMin": 140000,
-    "willPower": 60000
-  },
-  "spawnAreas": {
-    "bloodridge14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "blood vulture",
-    "b",
-    "v",
-    "blood",
-    "vulture"
-  ]
-}
diff --git a/world/npcs/change_spawn_interval_tick.sh b/world/npcs/change_spawn_interval_tick.sh
deleted file mode 100755
index 01e91f815dcbe4b134918d58687ae4a32cf56af7..0000000000000000000000000000000000000000
--- a/world/npcs/change_spawn_interval_tick.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-for file in $(ls *.json)
-do
-	echo "sed 's/^.*spawnIntervalTick.*$/      \"spawnIntervalTicks\": 600,/g' ${file} | tee ${file}"
-done
diff --git a/world/npcs/charlesbiggers.json b/world/npcs/charlesbiggers.json
deleted file mode 100755
index 149b651360d9056031b6d0ee2de0ef9c8883aa19..0000000000000000000000000000000000000000
--- a/world/npcs/charlesbiggers.json
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-  "name": "charles biggers",
-  "colorName": "charles \u001B[1m\u001B[35mbiggers\u001B[0m",
-  "dieMessage": "the charles \u001B[1m\u001B[35mbiggers\u001B[0m cries BROOOOOOOOOOOOOOOOOOOOO as he breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 15000,
-    "lootGoldMax": 20000,
-    "lootItems": [40, 41, 47, 48, 49, 50, 51, 52, 158]
-  },
-  "roamAreas": [
-    "tisland3_zone",
-    "tisland4_zone"
-  ],
-  "stats": {
-    "agile": 50,
-    "aim": 50,
-    "armorRating": 300,
-    "currentHealth": 40000,
-    "currentMana": 100,
-    "experience": 50000,
-    "maxHealth": 40000,
-    "maxMana": 100,
-    "meleSkill": 200,
-    "numberOfWeaponRolls": 5,
-    "strength": 500,
-    "weaponRatingMax": 500,
-    "weaponRatingMin": 300,
-    "willPower": 16
-  },
-  "spawnAreas": {
-    "tisland10_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "charles biggers",
-    "b",
-    "charles",
-    "c",
-    "biggers",
-    "watchy"
-  ]
-}
diff --git a/world/npcs/cherufe.json b/world/npcs/cherufe.json
deleted file mode 100644
index 7309b9b9e3d75753fa49d625e126bb06e3600914..0000000000000000000000000000000000000000
--- a/world/npcs/cherufe.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "cherufe",
-  "colorName": "\u001B[1m\u001B[35mcherufe\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mcherufe\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 52000000000,
-    "lootGoldMax": 62000000000,
-    "lootItems": [149]
-  },
-  "roamAreas": [
-    "bloodridge18_zone",
-    "bloodridge19_zone"
-  ],
-  "stats": {
-    "agile": 9600000,
-    "aim": 9502000,
-    "armorRating": 42000000,
-    "currentHealth": 2200000000,
-    "currentMana": 1300000000,
-    "experience": 11000000000,
-    "maxHealth": 2200000000,
-    "maxMana": 700000000,
-    "meleSkill": 104000000,
-    "numberOfWeaponRolls": 4000,
-    "strength": 91000000,
-    "weaponRatingMax": 168000000,
-    "weaponRatingMin": 105000000,
-    "willPower": 96000000
-  },
-  "spawnAreas": {
-    "bloodridge18_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    },
-    "bloodridge19_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }
-  },
-  "validTriggers": [
-    "cherufe",
-    "c"
-  ]
-}
diff --git a/world/npcs/cliffsatyr.json b/world/npcs/cliffsatyr.json
deleted file mode 100644
index 04ac12df5a0af1244f48734c5f88783798d3d8aa..0000000000000000000000000000000000000000
--- a/world/npcs/cliffsatyr.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "cliff satyr",
-  "colorName": "cliff \u001B[1m\u001B[35msatyr\u001B[0m",
-  "dieMessage": "the cliff \u001B[1m\u001B[35msatyr\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 50000000,
-    "lootGoldMax": 56000000,
-    "lootItems": [79]
-  },
-  "roamAreas": [
-    "bloodridge14_zone",
-    "bloodridge15_zone"
-  ],
-  "stats": {
-    "agile": 14000,
-    "aim": 18000,
-    "armorRating": 94000,
-    "currentHealth": 4000000,
-    "currentMana": 2400000,
-    "experience": 24000000,
-    "maxHealth": 5000000,
-    "maxMana": 1600000,
-    "meleSkill": 140000,
-    "numberOfWeaponRolls": 25,
-    "strength": 180000,
-    "weaponRatingMax": 210000,
-    "weaponRatingMin": 80000,
-    "willPower": 50000
-  },
-  "spawnAreas": {
-    "bloodridge14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "cliff satyr",
-    "c",
-    "s",
-    "cliff",
-    "satyr"
-  ]
-}
diff --git a/world/npcs/deathgriffin.json b/world/npcs/deathgriffin.json
deleted file mode 100755
index a02a62a75a61847ef6f846b7501a44964ea6c6bd..0000000000000000000000000000000000000000
--- a/world/npcs/deathgriffin.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
-  "name": "death griffin",
-  "colorName": "death \u001B[1m\u001B[35mgriffin\u001B[0m",
-  "dieMessage": "a death \u001B[1m\u001B[35mgriffin\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 60,
-    "lootGoldMax": 80,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "western8_zone",
-    "western9_zone"
-  ],
-  "stats": {
-    "agile": 24,
-    "aim": 24,
-    "armorRating": 20,
-    "currentHealth": 1000,
-    "currentMana": 100,
-    "experience": 2100,
-    "maxHealth": 1000,
-    "maxMana": 100,
-    "meleSkill": 19,
-    "numberOfWeaponRolls": 1,
-    "strength": 55,
-    "weaponRatingMax": 65,
-    "weaponRatingMin": 20,
-    "willPower": 30
-  },
-  "spawnAreas": {
-    "western8_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "western9_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "death",
-    "d",
-    "death griffin",
-    "death",
-    "griffin",
-    "g"
-  ]
-}
diff --git a/world/npcs/demonicelf.json b/world/npcs/demonicelf.json
deleted file mode 100644
index 0837576d9275484297bab26d8496dc49b54b5b72..0000000000000000000000000000000000000000
--- a/world/npcs/demonicelf.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "demonic elf",
-  "colorName": "demonic \u001B[1m\u001B[35melf\u001B[0m",
-  "dieMessage": "the demonic \u001B[1m\u001B[35melf\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 25000000,
-    "lootGoldMax": 34000000,
-    "lootItems": [75]
-  },
-  "roamAreas": [
-    "bloodridge12_zone",
-    "bloodridge13_zone"
-  ],
-  "stats": {
-    "agile": 7000,
-    "aim": 9000,
-    "armorRating": 47000,
-    "currentHealth": 2000000,
-    "currentMana": 1200000,
-    "experience": 14500000,
-    "maxHealth": 2500000,
-    "maxMana": 800000,
-    "meleSkill": 70000,
-    "numberOfWeaponRolls": 20,
-    "strength": 110000,
-    "weaponRatingMax": 125000,
-    "weaponRatingMin": 90000,
-    "willPower": 30000
-  },
-  "spawnAreas": {
-    "bloodridge12_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge13_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "demonic elf",
-    "d",
-    "e",
-    "demonic",
-    "elf"
-  ]
-}
diff --git a/world/npcs/demonsuccubus.json b/world/npcs/demonsuccubus.json
deleted file mode 100755
index 45cce2d5797725580cb1e7c4a6692be2e13e03e7..0000000000000000000000000000000000000000
--- a/world/npcs/demonsuccubus.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
-  "name": "demon succubus",
-  "colorName": "demon \u001B[1m\u001B[35msuccubus\u001B[0m",
-  "dieMessage": "a demon \u001B[1m\u001B[35msuccubus\u001B[0m breathes her last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 120,
-    "lootGoldMax": 180,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "western9_zone",
-    "western10_zone"
-  ],
-  "stats": {
-    "agile": 14,
-    "aim": 14,
-    "armorRating": 25,
-    "currentHealth": 1200,
-    "currentMana": 300,
-    "experience": 2600,
-    "maxHealth": 1200,
-    "maxMana": 100,
-    "meleSkill": 19,
-    "numberOfWeaponRolls": 1,
-    "strength": 70,
-    "weaponRatingMax": 60,
-    "weaponRatingMin": 35,
-    "willPower": 35
-  },
-  "spawnAreas": {
-    "western9_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "western10_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "demon",
-    "d",
-    "demon succubus",
-    "demon",
-    "succubus",
-    "s"
-  ]
-}
diff --git a/world/npcs/dhampir.json b/world/npcs/dhampir.json
deleted file mode 100644
index 3fbfd24ff9e67fd35bcb8987a81faf6998b569f0..0000000000000000000000000000000000000000
--- a/world/npcs/dhampir.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "dhampir",
-  "colorName": "\u001B[1m\u001B[35mdhampir\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mdhampir\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 2600000000000,
-    "lootGoldMax": 3100000000000,
-    "lootItems": [156]
-  },
-  "roamAreas": [
-    "bloodridge20_zone"
-  ],
-  "stats": {
-    "agile": 480000000,
-    "aim": 500020000,
-    "armorRating": 2000000000,
-    "currentHealth": 100000000000,
-    "currentMana": 70000000000,
-    "experience": 550000000000,
-    "maxHealth": 110000000000,
-    "maxMana": 35000000000,
-    "meleSkill": 5200000000,
-    "numberOfWeaponRolls": 200000,
-    "strength": 4600000000,
-    "weaponRatingMax": 7000000000,
-    "weaponRatingMin": 5250000000,
-    "willPower": 4600000000
-  },
-  "spawnAreas": {
-    "bloodridge20_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "dhampir",
-    "d"
-  ]
-}
diff --git a/world/npcs/drunkentroll.json b/world/npcs/drunkentroll.json
deleted file mode 100644
index 6f0e4ca3c49f500d903a0183326c9a039f58f2de..0000000000000000000000000000000000000000
--- a/world/npcs/drunkentroll.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "drunken troll",
-  "colorName": "drunken \u001B[1m\u001B[35mtroll\u001B[0m",
-  "dieMessage": "the drunken \u001B[1m\u001B[35mtroll\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 500000000,
-    "lootGoldMax": 700000000,
-    "lootItems": [106]
-  },
-  "roamAreas": [
-    "north14_zone",
-    "north15_zone"
-  ],
-  "stats": {
-    "agile": 120000,
-    "aim": 148000,
-    "armorRating": 700000,
-    "currentHealth": 30000000,
-    "currentMana": 12000000,
-    "experience": 220000000,
-    "maxHealth": 30000000,
-    "maxMana": 9600000,
-    "meleSkill": 1200000,
-    "numberOfWeaponRolls": 65,
-    "strength": 1500000,
-    "weaponRatingMax": 1900000,
-    "weaponRatingMin": 1500000,
-    "willPower": 800000
-  },
-  "spawnAreas": {
-    "north14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "north15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "drunken troll",
-    "t",
-    "d",
-    "drunken",
-    "troll"
-  ]
-}
diff --git a/world/npcs/dwarfvaettir.json b/world/npcs/dwarfvaettir.json
deleted file mode 100755
index 5712e89c3c8d0f2ab69536cd9edc68fdbf3b7624..0000000000000000000000000000000000000000
--- a/world/npcs/dwarfvaettir.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "dwarf vaettir",
-  "colorName": "dwarf \u001B[1m\u001B[35mvaettir\u001B[0m",
-  "dieMessage": "a dwarf \u001B[1m\u001B[35mvaettir\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 100,
-    "lootGoldMax": 229,
-    "lootItems": [36, 38]
-  },
-  "roamAreas": [
-    "north10_zone",
-    "north11_zone"
-  ],
-  "stats": {
-    "agile": 5,
-    "aim": 32,
-    "armorRating": 30,
-    "currentHealth": 3500,
-    "currentMana": 100,
-    "experience": 3200,
-    "maxHealth": 3500,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 100,
-    "weaponRatingMax": 90,
-    "weaponRatingMin": 50,
-    "willPower": 9
-  },
-  "spawnAreas": {
-    "north10_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 20
-    },
-    "north11_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "dwarf",
-    "d",
-    "dwarf vaettir",
-    "vaettir",
-    "v"
-  ]
-}
diff --git a/world/npcs/ferroclopus.json b/world/npcs/ferroclopus.json
deleted file mode 100644
index a2e893ec7fd9477b9909ee9502a015552c8e829e..0000000000000000000000000000000000000000
--- a/world/npcs/ferroclopus.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "ferroclopus",
-  "colorName": "\u001B[1m\u001B[35mferroclopus\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mferroclopus\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 260000000000,
-    "lootGoldMax": 310000000000,
-    "lootItems": [151]
-  },
-  "roamAreas": [
-    "bloodridge18_zone",
-    "bloodridge19_zone"
-  ],
-  "stats": {
-    "agile": 48000000,
-    "aim": 50002000,
-    "armorRating": 200000000,
-    "currentHealth": 10000000000,
-    "currentMana": 7000000000,
-    "experience": 55000000000,
-    "maxHealth": 11000000000,
-    "maxMana": 3500000000,
-    "meleSkill": 520000000,
-    "numberOfWeaponRolls": 20000,
-    "strength": 460000000,
-    "weaponRatingMax": 700000000,
-    "weaponRatingMin": 525000000,
-    "willPower": 460000000
-  },
-  "spawnAreas": {
-    "bloodridge18_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    },
-    "bloodridge19_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "ferroclopus",
-    "f"
-  ]
-}
diff --git a/world/npcs/fieldtroll.json b/world/npcs/fieldtroll.json
deleted file mode 100644
index d939766fc90a47b222afbcbbaba8c6e27ff05042..0000000000000000000000000000000000000000
--- a/world/npcs/fieldtroll.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "field troll",
-  "colorName": "field \u001B[1m\u001B[35mtroll\u001B[0m",
-  "dieMessage": "the field \u001B[1m\u001B[35mtroll\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 5700000,
-    "lootGoldMax": 8000000,
-    "lootItems": [69]
-  },
-  "roamAreas": [
-    "western3_zone",
-    "western4_zone"
-  ],
-  "stats": {
-    "agile": 3000,
-    "aim": 4000,
-    "armorRating": 10000,
-    "currentHealth": 1100000,
-    "currentMana": 1200000,
-    "experience": 5100000,
-    "maxHealth": 1000000,
-    "maxMana": 800000,
-    "meleSkill": 15000,
-    "numberOfWeaponRolls": 15,
-    "strength": 27000,
-    "weaponRatingMax": 30000,
-    "weaponRatingMin": 23000,
-    "willPower": 12000
-  },
-  "spawnAreas": {
-    "western3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "western4_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "field troll",
-    "f",
-    "t",
-    "field",
-    "troll"
-  ]
-}
diff --git a/world/npcs/firechimera.json b/world/npcs/firechimera.json
deleted file mode 100644
index 418079394511517a1b2ba885fd7662777346ba7f..0000000000000000000000000000000000000000
--- a/world/npcs/firechimera.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "fire chimera",
-  "colorName": "fire \u001B[1m\u001B[35mchimera\u001B[0m",
-  "dieMessage": "a fire \u001B[1m\u001B[35mchimera\u001B[0m lets out a blood curdling scream as it collapses and dies.",
-  "loot": {
-    "lootGoldMin": 1000000,
-    "lootGoldMax": 1750000,
-    "lootItems": [61, 62]
-  },
-  "roamAreas": [
-    "tisland6_zone",
-    "tisland7_zone"
-  ],
-  "stats": {
-    "agile": 1400,
-    "aim": 1400,
-    "armorRating": 6000,
-    "currentHealth": 600000,
-    "currentMana": 600000,
-    "experience": 1500000,
-    "maxHealth": 550000,
-    "maxMana": 500000,
-    "meleSkill": 8000,
-    "numberOfWeaponRolls": 15,
-    "strength": 10100,
-    "weaponRatingMax": 12300,
-    "weaponRatingMin": 4300,
-    "willPower": 8000
-  },
-  "spawnAreas": {
-    "tisland6_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 4
-    }, 
-    "tisland7_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }  
-  },
-  "validTriggers": [
-    "fire chimera",
-    "f",
-    "c",
-    "chimera",
-    "fire"
-  ]
-}
diff --git a/world/npcs/forestbysen.json b/world/npcs/forestbysen.json
deleted file mode 100755
index 8fe04b40eb3bda03a9fa4630ac039861d6eab4b4..0000000000000000000000000000000000000000
--- a/world/npcs/forestbysen.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-  "name": "forest bysen",
-  "colorName": "forest \u001B[1m\u001B[35mbysen\u001B[0m",
-  "dieMessage": "a forest \u001B[1m\u001B[35mbysen\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 300,
-    "lootGoldMax": 400,
-    "lootItems": [39]
-  },
-  "roamAreas": [
-    "south1_zone"
-  ],
-  "stats": {
-    "agile": 35,
-    "aim": 32,
-    "armorRating": 70,
-    "currentHealth": 6500,
-    "currentMana": 100,
-    "experience": 9200,
-    "maxHealth": 6500,
-    "maxMana": 100,
-    "meleSkill": 30,
-    "numberOfWeaponRolls": 1,
-    "strength": 170,
-    "weaponRatingMax": 180,
-    "weaponRatingMin": 150,
-    "willPower": 9
-  },
-  "spawnAreas": {
-    "south1_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 18
-    }
-  },
-  "validTriggers": [
-    "forest",
-    "bysen",
-    "forest bysen",
-    "b",
-    "f"
-  ]
-}
diff --git a/world/npcs/forestsatyr.json b/world/npcs/forestsatyr.json
deleted file mode 100644
index 8a5a463cc5a4f5056c2278a9b3dee690bcffe469..0000000000000000000000000000000000000000
--- a/world/npcs/forestsatyr.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "forest satyr",
-  "colorName": "forest \u001B[1m\u001B[35msatyr\u001B[0m",
-  "dieMessage": "the forest \u001B[1m\u001B[35msatyr\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 700000000,
-    "lootGoldMax": 900000000,
-    "lootItems": [107]
-  },
-  "roamAreas": [
-    "north14_zone",
-    "north15_zone"
-  ],
-  "stats": {
-    "agile": 140000,
-    "aim": 128000,
-    "armorRating": 600000,
-    "currentHealth": 30000000,
-    "currentMana": 22000000,
-    "experience": 200000000,
-    "maxHealth": 30000000,
-    "maxMana": 12000000,
-    "meleSkill": 1500000,
-    "numberOfWeaponRolls": 75,
-    "strength": 1250000,
-    "weaponRatingMax": 2200000,
-    "weaponRatingMin": 1300000,
-    "willPower": 1100000
-  },
-  "spawnAreas": {
-    "north14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "north15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "forest satyr",
-    "f",
-    "s",
-    "forest",
-    "satyr"
-  ]
-}
diff --git a/world/npcs/funneliktomi.json b/world/npcs/funneliktomi.json
deleted file mode 100644
index 339db5219364cacda0842730ed3daa4fcfc64637..0000000000000000000000000000000000000000
--- a/world/npcs/funneliktomi.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "funnel iktomi",
-  "colorName": "funnel \u001B[1m\u001B[35miktomi\u001B[0m",
-  "dieMessage": "the funnel \u001B[1m\u001B[35miktomi\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 200000000,
-    "lootGoldMax": 250000000,
-    "lootItems": [84]
-  },
-  "roamAreas": [
-    "tisland8_zone",
-    "tisland9_zone"
-  ],
-  "stats": {
-    "agile": 50000,
-    "aim": 65000,
-    "armorRating": 300000,
-    "currentHealth": 12000000,
-    "currentMana": 73000000,
-    "experience": 90000000,
-    "maxHealth": 12000000,
-    "maxMana": 5200000,
-    "meleSkill": 500000,
-    "numberOfWeaponRolls": 30,
-    "strength": 710000,
-    "weaponRatingMax": 850000,
-    "weaponRatingMin": 620000,
-    "willPower": 300000
-  },
-  "spawnAreas": {
-    "tisland8_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "tisland9_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "funnel iktomi",
-    "f",
-    "i",
-    "funnel",
-    "iktomi"
-  ]
-}
diff --git a/world/npcs/garmr.json b/world/npcs/garmr.json
deleted file mode 100644
index 37ed5d6931f8bf5d50f81d11d4cbee9a78c2d55f..0000000000000000000000000000000000000000
--- a/world/npcs/garmr.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "garmr",
-  "colorName": "\u001B[1m\u001B[35mgarmr\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mgarmr\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 26400000000,
-    "lootGoldMax": 31200000000,
-    "lootItems": [147]
-  },
-  "roamAreas": [
-    "toft5_zone"
-  ],
-  "stats": {
-    "agile": 4800000,
-    "aim": 4752000,
-    "armorRating": 21600000,
-    "currentHealth": 1080000000,
-    "currentMana": 816000000,
-    "experience": 6960000000,
-    "maxHealth": 1080000000,
-    "maxMana": 384000000,
-    "meleSkill": 55200000,
-    "numberOfWeaponRolls": 2000,
-    "strength": 46800000,
-    "weaponRatingMax": 84000000,
-    "weaponRatingMin": 52800000,
-    "willPower": 48000000
-  },
-  "spawnAreas": {
-    "toft5_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "garmr",
-    "g"
-  ]
-}
diff --git a/world/npcs/giantjohul.json b/world/npcs/giantjohul.json
deleted file mode 100644
index 0a8a4c95ad83751362e6c2c3919a61fb548df0c0..0000000000000000000000000000000000000000
--- a/world/npcs/giantjohul.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "giant johul",
-  "colorName": "giant \u001B[1m\u001B[35mjohul\u001B[0m",
-  "dieMessage": "the giant \u001B[1m\u001B[35mjohul\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1100000000,
-    "lootGoldMax": 1300000000,
-    "lootItems": [115]
-  },
-  "roamAreas": [
-    "bloodridge16_zone",
-    "bloodridge17_zone"
-  ],
-  "stats": {
-    "agile": 200000,
-    "aim": 198000,
-    "armorRating": 900000,
-    "currentHealth": 45000000,
-    "currentMana": 34000000,
-    "experience": 290000000,
-    "maxHealth": 45000000,
-    "maxMana": 16000000,
-    "meleSkill": 2300000,
-    "numberOfWeaponRolls": 85,
-    "strength": 2250000,
-    "weaponRatingMax": 4000000,
-    "weaponRatingMin": 2900000,
-    "willPower": 2000000
-  },
-  "spawnAreas": {
-    "bloodridge16_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge17_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "giant johul",
-    "g",
-    "j",
-    "giant",
-    "johul"
-  ]
-}
diff --git a/world/npcs/glacierdwarf.json b/world/npcs/glacierdwarf.json
deleted file mode 100644
index 0e439db3171af31238f649fafe203173258f76c7..0000000000000000000000000000000000000000
--- a/world/npcs/glacierdwarf.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "glacier dwarf",
-  "colorName": "glacier \u001B[1m\u001B[35mdwarf\u001B[0m",
-  "dieMessage": "the glacier \u001B[1m\u001B[35mdwarf\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 500000000,
-    "lootGoldMax": 700000000,
-    "lootItems": [110]
-  },
-  "roamAreas": [
-    "bloodridge16_zone",
-    "bloodridge17_zone"
-  ],
-  "stats": {
-    "agile": 120000,
-    "aim": 148000,
-    "armorRating": 700000,
-    "currentHealth": 30000000,
-    "currentMana": 12000000,
-    "experience": 220000000,
-    "maxHealth": 30000000,
-    "maxMana": 9600000,
-    "meleSkill": 1200000,
-    "numberOfWeaponRolls": 65,
-    "strength": 1500000,
-    "weaponRatingMax": 1900000,
-    "weaponRatingMin": 1500000,
-    "willPower": 800000
-  },
-  "spawnAreas": {
-    "bloodridge16_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge17_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "glacier dwarf",
-    "g",
-    "d",
-    "glacier",
-    "dwarf"
-  ]
-}
diff --git a/world/npcs/goblinastronomer.json b/world/npcs/goblinastronomer.json
deleted file mode 100644
index b763dee4a612e1ed25bb3933b80c252ff9a0599b..0000000000000000000000000000000000000000
--- a/world/npcs/goblinastronomer.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "goblin astronomer",
-  "colorName": "goblin \u001B[1m\u001B[35mastronomer\u001B[0m",
-  "dieMessage": "the goblin \u001B[1m\u001B[35mastronomer\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 700000000,
-    "lootGoldMax": 900000000,
-    "lootItems": [112]
-  },
-  "roamAreas": [
-    "bloodridge16_zone",
-    "bloodridge17_zone"
-  ],
-  "stats": {
-    "agile": 140000,
-    "aim": 128000,
-    "armorRating": 600000,
-    "currentHealth": 30000000,
-    "currentMana": 22000000,
-    "experience": 200000000,
-    "maxHealth": 30000000,
-    "maxMana": 12000000,
-    "meleSkill": 1500000,
-    "numberOfWeaponRolls": 75,
-    "strength": 1250000,
-    "weaponRatingMax": 2200000,
-    "weaponRatingMin": 1300000,
-    "willPower": 1100000
-  },
-  "spawnAreas": {
-    "bloodridge16_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge17_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "goblin astronomer",
-    "g",
-    "a",
-    "goblin",
-    "astronomer"
-  ]
-}
diff --git a/world/npcs/goblinnobleman.json b/world/npcs/goblinnobleman.json
deleted file mode 100644
index 3482e2ca600de02675a9e8935c7ea215ee363606..0000000000000000000000000000000000000000
--- a/world/npcs/goblinnobleman.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "goblin nobleman",
-  "colorName": "goblin \u001B[1m\u001B[35mnobleman\u001B[0m",
-  "dieMessage": "the goblin \u001B[1m\u001B[35mnobleman\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1000000000,
-    "lootGoldMax": 1200000000,
-    "lootItems": [114]
-  },
-  "roamAreas": [
-    "bloodridge16_zone",
-    "bloodridge17_zone"
-  ],
-  "stats": {
-    "agile": 190000,
-    "aim": 188000,
-    "armorRating": 800000,
-    "currentHealth": 42000000,
-    "currentMana": 32000000,
-    "experience": 270000000,
-    "maxHealth": 42000000,
-    "maxMana": 12000000,
-    "meleSkill": 2100000,
-    "numberOfWeaponRolls": 85,
-    "strength": 1850000,
-    "weaponRatingMax": 3200000,
-    "weaponRatingMin": 2300000,
-    "willPower": 1900000
-  },
-  "spawnAreas": {
-    "bloodridge16_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge17_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "goblin nobleman",
-    "g",
-    "n",
-    "goblin",
-    "nobleman"
-  ]
-}
diff --git a/world/npcs/goldenstrix.json b/world/npcs/goldenstrix.json
deleted file mode 100644
index 156d808bb3406953552e7a8f76eeadb4853b867e..0000000000000000000000000000000000000000
--- a/world/npcs/goldenstrix.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "golden strix",
-  "colorName": "golden \u001B[1m\u001B[35mstrix\u001B[0m",
-  "dieMessage": "the golden \u001B[1m\u001B[35mstrix\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 7500000,
-    "lootGoldMax": 10000000,
-    "lootItems": [67, 68]
-  },
-  "roamAreas": [
-    "tisland6_zone",
-    "tisland7_zone"
-  ],
-  "stats": {
-    "agile": 3000,
-    "aim": 4000,
-    "armorRating": 10000,
-    "currentHealth": 1800000,
-    "currentMana": 1200000,
-    "experience": 5100000,
-    "maxHealth": 1000000,
-    "maxMana": 800000,
-    "meleSkill": 15000,
-    "numberOfWeaponRolls": 15,
-    "strength": 27000,
-    "weaponRatingMax": 20000,
-    "weaponRatingMin": 13000,
-    "willPower": 12000
-  },
-  "spawnAreas": {
-    "tisland6_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "tisland7_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "golden strix",
-    "g",
-    "s",
-    "strix",
-    "golden"
-  ]
-}
diff --git a/world/npcs/grayekimmu.json b/world/npcs/grayekimmu.json
deleted file mode 100755
index 02dc8039235bfa9d6039d63f470274a4c04f758a..0000000000000000000000000000000000000000
--- a/world/npcs/grayekimmu.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "gray ekimmu",
-  "colorName": "gray \u001B[1m\u001B[35mekimmu\u001B[0m",
-  "dieMessage": "a gray \u001B[1m\u001B[35mekimmu\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 12,
-    "lootGoldMax": 24,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "north4_zone",
-    "north5_zone"
-  ],
-  "stats": {
-    "agile": 4,
-    "aim": 4,
-    "armorRating": 11,
-    "currentHealth": 450,
-    "currentMana": 300,
-    "experience": 450,
-    "maxHealth": 450,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 20,
-    "weaponRatingMax": 18,
-    "weaponRatingMin": 12,
-    "willPower": 4
-  },
-  "spawnAreas": {
-    "north4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }, 
-    "north5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "g",
-    "gray ekimmu",
-    "gray",
-    "ekimmu",
-    "e"
-  ]
-}
diff --git a/world/npcs/graylindorm.json b/world/npcs/graylindorm.json
deleted file mode 100644
index db8c08a7f13e9e59e298b621a6b08443ed47b2e5..0000000000000000000000000000000000000000
--- a/world/npcs/graylindorm.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-  "name": "gray lindorm",
-  "colorName": "gray \u001B[1m\u001B[35mlindorm\u001B[0m",
-  "dieMessage": "the gray \u001B[1m\u001B[35mlindorm\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 4160000000000,
-    "lootGoldMax": 4960000000000,
-    "lootItems": [157]
-  },
-  "roamAreas": [
-    "bloodridge20_zone"
-  ],
-  "stats": {
-    "agile": 768000000,
-    "aim": 800002000,
-    "armorRating": 3200000000,
-    "currentHealth": 160000000000,
-    "currentMana": 112000000000,
-    "experience": 885000000000,
-    "maxHealth": 161000000000,
-    "maxMana": 56000000000,
-    "meleSkill": 8020000000,
-    "numberOfWeaponRolls": 320000,
-    "strength": 7360000000,
-    "weaponRatingMax": 11200000000,
-    "weaponRatingMin": 8025000000,
-    "willPower": 7300000000
-  },
-  "spawnAreas": {
-    "bloodridge20_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "gray lindorm",
-    "lindorm",
-    "gray",
-    "g",
-    "l"
-  ]
-}
diff --git a/world/npcs/greathellhound.json b/world/npcs/greathellhound.json
deleted file mode 100644
index 1cde9a7c8d5ec4ad642d30da6d1e567e2f3b822c..0000000000000000000000000000000000000000
--- a/world/npcs/greathellhound.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "name": "great hellhound",
-  "colorName": "great \u001B[1m\u001B[35mhellhound\u001B[0m",
-  "dieMessage": "a great \u001B[1m\u001B[35mhellhound\u001B[0m screams in agony as it dies.",
-  "loot": {
-    "lootGoldMin": 300000,
-    "lootGoldMax": 600000,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "south2_zone",
-    "south3_zone"
-  ],
-  "stats": {
-    "agile": 400,
-    "aim": 400,
-    "armorRating": 1440,
-    "currentHealth": 300000,
-    "currentMana": 300000,
-    "experience": 250000,
-    "maxHealth": 300000,
-    "maxMana": 300000,
-    "meleSkill": 2400,
-    "numberOfWeaponRolls": 15,
-    "strength": 4000,
-    "weaponRatingMax": 4000,
-    "weaponRatingMin": 2300,
-    "willPower": 4000
-  },
-  "spawnAreas": {
-    "south2_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "south3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "great hellhound",
-    "g",
-    "h",
-    "hellhound"
-  ]
-}
diff --git a/world/npcs/grootslang.json b/world/npcs/grootslang.json
deleted file mode 100644
index 6bb339826ab6afe72d215ef8e03ff51f38ec456d..0000000000000000000000000000000000000000
--- a/world/npcs/grootslang.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "grootslang",
-  "colorName": "\u001B[1m\u001B[35mgrootslang\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mgrootslang\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 11000000000,
-    "lootGoldMax": 13000000000,
-    "lootItems": [146]
-  },
-  "roamAreas": [
-    "toft5_zone"
-  ],
-  "stats": {
-    "agile": 2000000,
-    "aim": 1980000,
-    "armorRating": 9000000,
-    "currentHealth": 450000000,
-    "currentMana": 340000000,
-    "experience": 2900000000,
-    "maxHealth": 450000000,
-    "maxMana": 160000000,
-    "meleSkill": 23000000,
-    "numberOfWeaponRolls": 850,
-    "strength": 19500000,
-    "weaponRatingMax": 35000000,
-    "weaponRatingMin": 22000000,
-    "willPower": 20000000
-  },
-  "spawnAreas": {
-    "toft5_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    } 
-  },
-  "validTriggers": [
-    "grootslang",
-    "g"
-  ]
-}
diff --git a/world/npcs/highlandnymph.json b/world/npcs/highlandnymph.json
deleted file mode 100644
index 8260f614f34d2e2384fb90e1037387efe4753f68..0000000000000000000000000000000000000000
--- a/world/npcs/highlandnymph.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-  "name": "highland nymph",
-  "colorName": "highland \u001B[1m\u001B[35mnymph\u001B[0m",
-  "dieMessage": "the highland \u001B[1m\u001B[35mnymph\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1800000000000,
-    "lootGoldMax": 2400000000000,
-    "lootItems": [155]
-  },
-  "roamAreas": [
-    "bloodridge20_zone"
-  ],
-  "stats": {
-    "agile": 380000000,
-    "aim": 400002000,
-    "armorRating": 1600000000,
-    "currentHealth": 80000000000,
-    "currentMana": 56000000000,
-    "experience": 440000000000,
-    "maxHealth": 88000000000,
-    "maxMana": 28000000000,
-    "meleSkill": 4100000000,
-    "numberOfWeaponRolls": 160000,
-    "strength": 3840000000,
-    "weaponRatingMax": 5600000000,
-    "weaponRatingMin": 4005000000,
-    "willPower": 3300000000
-  },
-  "spawnAreas": {
-    "bloodridge20_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "highland nymph",
-    "highland",
-    "nymph",
-    "h",
-    "n"
-  ]
-}
diff --git a/world/npcs/highlandwarrior.json b/world/npcs/highlandwarrior.json
deleted file mode 100644
index 8531baf4ea286bbc88f2ea4586581342793c19a3..0000000000000000000000000000000000000000
--- a/world/npcs/highlandwarrior.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "highland warrior",
-  "colorName": "highland \u001B[1m\u001B[35mwarrior\u001B[0m",
-  "dieMessage": "the highland \u001B[1m\u001B[35mwarrior\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 50000000,
-    "lootGoldMax": 68000000,
-    "lootItems": [77]
-  },
-  "roamAreas": [
-    "bloodridge14_zone",
-    "bloodridge15_zone"
-  ],
-  "stats": {
-    "agile": 14000,
-    "aim": 18000,
-    "armorRating": 94000,
-    "currentHealth": 4000000,
-    "currentMana": 2400000,
-    "experience": 29000000,
-    "maxHealth": 5000000,
-    "maxMana": 1600000,
-    "meleSkill": 140000,
-    "numberOfWeaponRolls": 20,
-    "strength": 220000,
-    "weaponRatingMax": 250000,
-    "weaponRatingMin": 180000,
-    "willPower": 60000
-  },
-  "spawnAreas": {
-    "bloodridge14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "highland warrior",
-    "h",
-    "w",
-    "highland",
-    "warrior"
-  ]
-}
diff --git a/world/npcs/hippogriff.json b/world/npcs/hippogriff.json
deleted file mode 100644
index 5eb57bc5d965a114233cf1b5318e6900afb63a58..0000000000000000000000000000000000000000
--- a/world/npcs/hippogriff.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "hippogriff",
-  "colorName": "\u001B[1m\u001B[35mhippogriff\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mhippogriff\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1000000000000,
-    "lootGoldMax": 1200000000000,
-    "lootItems": [153]
-  },
-  "roamAreas": [
-    "bloodridge19_zone",
-    "bloodridge20_zone"
-  ],
-  "stats": {
-    "agile": 192000000,
-    "aim": 200002000,
-    "armorRating": 800000000,
-    "currentHealth": 40000000000,
-    "currentMana": 25000000000,
-    "experience": 190000000000,
-    "maxHealth": 44000000000,
-    "maxMana": 14000000000,
-    "meleSkill": 2080000000,
-    "numberOfWeaponRolls": 80000,
-    "strength": 1900000000,
-    "weaponRatingMax": 2700000000,
-    "weaponRatingMin": 1905000000,
-    "willPower": 1800000000
-  },
-  "spawnAreas": {
-    "bloodridge19_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    },
-    "bloodridge20_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "hippogriff",
-    "h"
-  ]
-}
diff --git a/world/npcs/jotunsoldier.json b/world/npcs/jotunsoldier.json
deleted file mode 100644
index 3d8a98ff00b5e447ccbf7a25935cee0be2e32969..0000000000000000000000000000000000000000
--- a/world/npcs/jotunsoldier.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "jotun soldier",
-  "colorName": "jotun \u001B[1m\u001B[35msoldier\u001B[0m",
-  "dieMessage": "the jotun \u001B[1m\u001B[35msoldier\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 7500000,
-    "lootGoldMax": 10000000,
-    "lootItems": [70]
-  },
-  "roamAreas": [
-    "western3_zone",
-    "western4_zone"
-  ],
-  "stats": {
-    "agile": 4000,
-    "aim": 5000,
-    "armorRating": 10000,
-    "currentHealth": 1600000,
-    "currentMana": 1200000,
-    "experience": 6400000,
-    "maxHealth": 1000000,
-    "maxMana": 800000,
-    "meleSkill": 15000,
-    "numberOfWeaponRolls": 15,
-    "strength": 27000,
-    "weaponRatingMax": 26000,
-    "weaponRatingMin": 14000,
-    "willPower": 12000
-  },
-  "spawnAreas": {
-    "western3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "western4_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "jotun soldier",
-    "j",
-    "s",
-    "jotun",
-    "soldier"
-  ]
-}
diff --git a/world/npcs/lightningdruid.json b/world/npcs/lightningdruid.json
deleted file mode 100644
index 79a2496f78bee05f5bc29c65d2c4e2ebb759f45f..0000000000000000000000000000000000000000
--- a/world/npcs/lightningdruid.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "lightning druid",
-  "colorName": "lightning \u001B[1m\u001B[35mdruid\u001B[0m",
-  "dieMessage": "the lightning \u001B[1m\u001B[35mdruid\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 800000000,
-    "lootGoldMax": 1000000000,
-    "lootItems": [113]
-  },
-  "roamAreas": [
-    "bloodridge16_zone",
-    "bloodridge17_zone"
-  ],
-  "stats": {
-    "agile": 180000,
-    "aim": 178000,
-    "armorRating": 750000,
-    "currentHealth": 34000000,
-    "currentMana": 22000000,
-    "experience": 220000000,
-    "maxHealth": 34000000,
-    "maxMana": 12000000,
-    "meleSkill": 1400000,
-    "numberOfWeaponRolls": 80,
-    "strength": 1350000,
-    "weaponRatingMax": 2200000,
-    "weaponRatingMin": 1300000,
-    "willPower": 1100000
-  },
-  "spawnAreas": {
-    "bloodridge16_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge17_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "lightning",
-    "druid",
-    "l",
-    "d",
-    "lightning druid"
-  ]
-}
diff --git a/world/npcs/lonebarbarian.json b/world/npcs/lonebarbarian.json
deleted file mode 100644
index 475d14ee831304e92bbac956b60d56520eccf4a4..0000000000000000000000000000000000000000
--- a/world/npcs/lonebarbarian.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "lone barbarian",
-  "colorName": "lone \u001B[1m\u001B[35mbarbarian\u001B[0m",
-  "dieMessage": "the lone \u001B[1m\u001B[35mbarbarian\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 75000000,
-    "lootGoldMax": 100000000,
-    "lootItems": [81]
-  },
-  "roamAreas": [
-    "bloodridge14_zone",
-    "bloodridge15_zone"
-  ],
-  "stats": {
-    "agile": 21000,
-    "aim": 27000,
-    "armorRating": 123000,
-    "currentHealth": 5000000,
-    "currentMana": 3000000,
-    "experience": 40000000,
-    "maxHealth": 6000000,
-    "maxMana": 2400000,
-    "meleSkill": 210000,
-    "numberOfWeaponRolls": 30,
-    "strength": 330000,
-    "weaponRatingMax": 375000,
-    "weaponRatingMin": 270000,
-    "willPower": 100000
-  },
-  "spawnAreas": {
-    "bloodridge14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "lone barbarian",
-    "l",
-    "b",
-    "lone",
-    "barbarian"
-  ]
-}
diff --git a/world/npcs/luchtigen.json b/world/npcs/luchtigen.json
deleted file mode 100644
index f5c41326d68c8e43af8b36b49c0e4165357e6f4f..0000000000000000000000000000000000000000
--- a/world/npcs/luchtigen.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "luchtigen",
-  "colorName": "\u001B[1m\u001B[35mluchtigen\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mluchtigen\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 4400000000,
-    "lootGoldMax": 5200000000,
-    "lootItems": [145]
-  },
-  "roamAreas": [
-    "toft5_zone"
-  ],
-  "stats": {
-    "agile": 800000,
-    "aim": 850000,
-    "armorRating": 3800000,
-    "currentHealth": 200000000,
-    "currentMana": 140000000,
-    "experience": 1100000000,
-    "maxHealth": 180000000,
-    "maxMana": 64000000,
-    "meleSkill": 8500000,
-    "numberOfWeaponRolls": 165,
-    "strength": 8000000,
-    "weaponRatingMax": 14000000,
-    "weaponRatingMin": 8800000,
-    "willPower": 8000000
-  },
-  "spawnAreas": {
-    "toft5_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 3
-    }
-  },
-  "validTriggers": [
-    "luchtigen",
-    "l"
-  ]
-}
diff --git a/world/npcs/mountaingoblin.json b/world/npcs/mountaingoblin.json
deleted file mode 100644
index 700364fd4d18669986f559f2a6d0fb7403eac245..0000000000000000000000000000000000000000
--- a/world/npcs/mountaingoblin.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "mountain goblin",
-  "colorName": "mountain \u001B[1m\u001B[35mgoblin\u001B[0m",
-  "dieMessage": "the mountain \u001B[1m\u001B[35mgoblin\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1500000,
-    "lootGoldMax": 2000000,
-    "lootItems": [59, 60]
-  },
-  "roamAreas": [
-    "south3_zone",
-    "south4_zone"
-  ],
-  "stats": {
-    "agile": 1000,
-    "aim": 1000,
-    "armorRating": 3840,
-    "currentHealth": 600000,
-    "currentMana": 400000,
-    "experience": 1100000,
-    "maxHealth": 600000,
-    "maxMana": 400000,
-    "meleSkill": 5000,
-    "numberOfWeaponRolls": 15,
-    "strength": 9000,
-    "weaponRatingMax": 9000,
-    "weaponRatingMin": 4300,
-    "willPower": 4000
-  },
-  "spawnAreas": {
-    "south3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "south4_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "mountain goblin",
-    "m",
-    "g",
-    "goblin",
-    "mountain"
-  ]
-}
diff --git a/world/npcs/nemeanlion.json b/world/npcs/nemeanlion.json
deleted file mode 100644
index 8bce675cbbb77c310cae0c54c43452ce57cb5db6..0000000000000000000000000000000000000000
--- a/world/npcs/nemeanlion.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "nemean lion",
-  "colorName": "nemean \u001B[1m\u001B[35mlion\u001B[0m",
-  "dieMessage": "the nemean \u001B[1m\u001B[35mlion\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1500000,
-    "lootGoldMax": 2000000,
-    "lootItems": [64]
-  },
-  "roamAreas": [
-    "north12_zone",
-    "north13_zone"
-  ],
-  "stats": {
-    "agile": 1000,
-    "aim": 1000,
-    "armorRating": 3840,
-    "currentHealth": 600000,
-    "currentMana": 400000,
-    "experience": 1100000,
-    "maxHealth": 600000,
-    "maxMana": 400000,
-    "meleSkill": 5000,
-    "numberOfWeaponRolls": 15,
-    "strength": 9000,
-    "weaponRatingMax": 9000,
-    "weaponRatingMin": 4300,
-    "willPower": 4000
-  },
-  "spawnAreas": {
-    "north12_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "north13_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "nemean lion",
-    "n",
-    "l",
-    "nemean",
-    "lion"
-  ]
-}
diff --git a/world/npcs/nightmaretroll.json b/world/npcs/nightmaretroll.json
deleted file mode 100755
index 43e0ee232b41d765eb3ac2061c02d179b60c9852..0000000000000000000000000000000000000000
--- a/world/npcs/nightmaretroll.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "nightmare troll",
-  "colorName": "nightmare \u001B[1m\u001B[35mtroll\u001B[0m",
-  "dieMessage": "a nightmare \u001B[1m\u001B[35mtroll\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 20,
-    "lootGoldMax": 40,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "north7_zone",
-    "north8_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 6,
-    "armorRating": 18,
-    "currentHealth": 550,
-    "currentMana": 100,
-    "experience": 720,
-    "maxHealth": 550,
-    "maxMana": 100,
-    "meleSkill": 19,
-    "numberOfWeaponRolls": 1,
-    "strength": 34,
-    "weaponRatingMax": 32,
-    "weaponRatingMin": 5,
-    "willPower": 7
-  },
-  "spawnAreas": {
-    "north7_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "north8_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "nightmare",
-    "n",
-    "nightmare troll",
-    "troll",
-    "t"
-  ]
-}
diff --git a/world/npcs/nomadicsorceror.json b/world/npcs/nomadicsorceror.json
deleted file mode 100644
index d56803eeb01c4813ff6b0494a9b8e75df98c2bc3..0000000000000000000000000000000000000000
--- a/world/npcs/nomadicsorceror.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "nomadic sorceror",
-  "colorName": "nomadic \u001B[1m\u001B[35msorceror\u001B[0m",
-  "dieMessage": "the nomadic \u001B[1m\u001B[35msorceror\u001B[0m chants the incantation of death.",
-  "loot": {
-    "lootGoldMin": 150000000,
-    "lootGoldMax": 200000000,
-    "lootItems": [83]
-  },
-  "roamAreas": [
-    "tisland8_zone",
-    "tisland9_zone"
-  ],
-  "stats": {
-    "agile": 42000,
-    "aim": 54000,
-    "armorRating": 256000,
-    "currentHealth": 10000000,
-    "currentMana": 7000000,
-    "experience": 80000000,
-    "maxHealth": 12000000,
-    "maxMana": 7000000,
-    "meleSkill": 420000,
-    "numberOfWeaponRolls": 40,
-    "strength": 666666,
-    "weaponRatingMax": 750000,
-    "weaponRatingMin": 540000,
-    "willPower": 300000
-  },
-  "spawnAreas": {
-    "tisland8_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "tisland9_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "nomadic sorceror",
-    "n",
-    "s",
-    "nomadic",
-    "sorceror"
-  ]
-}
diff --git a/world/npcs/phantomknight.json b/world/npcs/phantomknight.json
deleted file mode 100755
index 30ce9541ba29cc0659e3b605704f33753276bbd6..0000000000000000000000000000000000000000
--- a/world/npcs/phantomknight.json
+++ /dev/null
@@ -1,59 +0,0 @@
-{
-  "name": "phantom knight",
-  "colorName": "phantom \u001B[1m\u001B[35mknight\u001B[0m",
-  "dieMessage": "a phantom \u001B[1m\u001B[35mknight\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 16,
-    "lootGoldMax": 32,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "bloodridge7_zone",
-    "bloodridge6_zone",
-    "bloodridge5_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 5,
-    "armorRating": 14,
-    "currentHealth": 500,
-    "currentMana": 300,
-    "experience": 600,
-    "maxHealth": 500,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 28,
-    "weaponRatingMax": 22,
-    "weaponRatingMin": 12,
-    "willPower": 5
-  },
-  "spawnAreas": {
-    "bloodridge5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "bloodridge6_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-    , 
-    "bloodridge7_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "p",
-    "phantom knight",
-    "phantom",
-    "knight",
-    "k"
-  ]
-}
diff --git a/world/npcs/phantomorc.json b/world/npcs/phantomorc.json
deleted file mode 100755
index d9cfc02cb837e7623ab0b99e609091ed22c32195..0000000000000000000000000000000000000000
--- a/world/npcs/phantomorc.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "phantom orc",
-  "colorName": "phantom \u001B[1m\u001B[35morc\u001B[0m",
-  "dieMessage": "a phantom \u001B[1m\u001B[35morc\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 16,
-    "lootGoldMax": 24,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "bloodridge4_zone",
-    "bloodridge5_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 5,
-    "armorRating": 9,
-    "currentHealth": 400,
-    "currentMana": 300,
-    "experience": 510,
-    "maxHealth": 400,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 16,
-    "weaponRatingMin": 12,
-    "weaponRatingMax": 25,
-    "willPower": 5
-  },
-  "spawnAreas": {
-    "bloodridge4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "bloodridge5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "p",
-    "phantom orc",
-    "phantom",
-    "orc",
-    "o"
-  ]
-}
diff --git a/world/npcs/phantomwizard.json b/world/npcs/phantomwizard.json
deleted file mode 100755
index 1cb75fa0f2fb459c33b76d666ca34391bb0fce0d..0000000000000000000000000000000000000000
--- a/world/npcs/phantomwizard.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "phantom wizard",
-  "colorName": "phantom \u001B[1m\u001B[35mwizard\u001B[0m",
-  "dieMessage": "a phantom \u001B[1m\u001B[35mwizard\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 16,
-    "lootGoldMax": 24,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "bloodridge4_zone",
-    "bloodridge5_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 5,
-    "armorRating": 9,
-    "currentHealth": 400,
-    "currentMana": 300,
-    "experience": 510,
-    "maxHealth": 400,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 16,
-    "weaponRatingMin": 12,
-    "weaponRatingMax": 25,
-    "willPower": 5
-  },
-  "spawnAreas": {
-    "bloodridge4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "bloodridge5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "p",
-    "phantom wizard",
-    "phantom",
-    "wizard",
-    "w"
-  ]
-}
diff --git a/world/npcs/phoenix.json b/world/npcs/phoenix.json
deleted file mode 100644
index 31936a0bbb2338051e37490ce78abe482fa9cba9..0000000000000000000000000000000000000000
--- a/world/npcs/phoenix.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "phoenix",
-  "colorName": "\u001B[1m\u001B[35mphoenix\u001B[0m",
-  "dieMessage": "a \u001B[1m\u001B[35mphoenix\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 105000,
-    "lootGoldMax": 150000,
-    "lootItems": [65]
-  },
-  "roamAreas": [
-    "north12_zone",
-    "north13_zone"
-  ],
-  "stats": {
-    "agile": 210,
-    "aim": 210,
-    "armorRating": 1500,
-    "currentHealth": 195000,
-    "currentMana": 500,
-    "experience": 1270000,
-    "maxHealth": 195000,
-    "maxMana": 300,
-    "meleSkill": 1200,
-    "numberOfWeaponRolls": 10,
-    "strength": 14400,
-    "weaponRatingMax": 41000,
-    "weaponRatingMin": 35000,
-    "willPower": 50
-  },
-  "spawnAreas": {
-    "north12_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 3
-    }, 
-    "north13_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    } 
-  },
-  "validTriggers": [
-    "phoenix",
-    "p"
-  ]
-}
diff --git a/world/npcs/razorclawwolf.json b/world/npcs/razorclawwolf.json
deleted file mode 100755
index 381f98cd1b2d9f420e24544287c9a05e4aa0fb9a..0000000000000000000000000000000000000000
--- a/world/npcs/razorclawwolf.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "razor-claw wolf",
-  "colorName": "razor-claw \u001B[1m\u001B[35mwolf\u001B[0m",
-  "dieMessage": "a razor-claw \u001B[1m\u001B[35mwolf\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 20,
-    "lootGoldMax": 30,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "toft2_zone",
-    "toft3_zone"
-  ],
-  "stats": {
-    "agile": 9,
-    "aim": 5,
-    "armorRating": 8,
-    "currentHealth": 500,
-    "currentMana": 100,
-    "experience": 600,
-    "maxHealth": 500,
-    "maxMana": 100,
-    "meleSkill": 12,
-    "numberOfWeaponRolls": 1,
-    "strength": 25,
-    "weaponRatingMax": 27,
-    "weaponRatingMin": 10,
-    "willPower": 7
-  },
-  "spawnAreas": {
-    "toft2_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "toft3_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "razor-claw",
-    "r",
-    "razor-claw wolf",
-    "wolf",
-    "w"
-  ]
-}
diff --git a/world/npcs/redeyedbear.json b/world/npcs/redeyedbear.json
old mode 100755
new mode 100644
index 9a15ad244934d05e3f4d857a6428090f39d83449..18ad613dbfa99cf33e46d6193b57b5b21eb09885
--- a/world/npcs/redeyedbear.json
+++ b/world/npcs/redeyedbear.json
@@ -1,10 +1,12 @@
+
 {
   "name": "red-eyed bear",
   "colorName": "red-eyed \u001B[1m\u001B[35mbear\u001B[0m",
   "dieMessage": "a red-eyed \u001B[1m\u001B[35mbear\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
+  "temperament": "aggressive",
   "loot": {
-    "lootGoldMin": 6,
-    "lootGoldMax": 20,
+    "lootGoldMin": 15,
+    "lootGoldMax": 25,
     "lootItems": []
   },
   "roamAreas": [
@@ -12,27 +14,33 @@
     "toft2_zone"
   ],
   "stats": {
-    "agile": 1,
-    "aim": 1,
-    "armorRating": 8,
-    "currentHealth": 230,
-    "currentMana": 100,
-    "experience": 250,
-    "maxHealth": 230,
-    "maxMana": 100,
-    "meleSkill": 6,
+    "agile": 6,
+    "aim": 3,
+    "armorRating": 20,
+    "currentHealth": 150,
+    "currentMana": 105,
+    "experience": 90000,
+    "maxHealth": 150,
+    "maxMana": 105,
+    "meleSkill": 22,
     "numberOfWeaponRolls": 1,
-    "strength": 11,
-    "weaponRatingMax": 13,
-    "weaponRatingMin": 10,
-    "willPower": 1
+    "strength": 13,
+    "weaponRatingMax": 22,
+    "weaponRatingMin": 16,
+    "willPower": 4
   },
   "spawnAreas": {
-    "bloodridge1_zone": {
+    "toft1_zone": {
       "randomChance": 100,
-      "maxPerRoom": 3,
+      "maxPerRoom": 1,
       "spawnIntervalTicks": 600,
-      "maxInstances": 14
+      "maxInstances": 22
+    },
+    "toft2_zone": {
+      "randomChance": 100,
+      "maxPerRoom": 1,
+      "spawnIntervalTicks": 600,
+      "maxInstances": 22
     }
   },
   "validTriggers": [
@@ -40,6 +48,7 @@
     "red-eyed bear",
     "red",
     "red-eyed",
-    "b"
+    "b",
+    "bear"
   ]
 }
diff --git a/world/npcs/ridgeleprechaun.json b/world/npcs/ridgeleprechaun.json
deleted file mode 100644
index 8fc8f1d3e7ade280a727b9ff6debb0f1072dd020..0000000000000000000000000000000000000000
--- a/world/npcs/ridgeleprechaun.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "ridge leprechaun",
-  "colorName": "ridge \u001B[1m\u001B[35mleprechaun\u001B[0m",
-  "dieMessage": "the ridge \u001B[1m\u001B[35mleprechaun\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1300000000000,
-    "lootGoldMax": 1800000000000,
-    "lootItems": [154]
-  },
-  "roamAreas": [
-    "bloodridge19_zone",
-    "bloodridge20_zone"
-  ],
-  "stats": {
-    "agile": 280000000,
-    "aim": 300002000,
-    "armorRating": 1200000000,
-    "currentHealth": 60000000000,
-    "currentMana": 42000000000,
-    "experience": 300000000000,
-    "maxHealth": 66000000000,
-    "maxMana": 21000000000,
-    "meleSkill": 3000000000,
-    "numberOfWeaponRolls": 120000,
-    "strength": 2660000000,
-    "weaponRatingMax": 4200000000,
-    "weaponRatingMin": 3105000000,
-    "willPower": 2600000000
-  },
-  "spawnAreas": {
-    "bloodridge19_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    },
-    "bloodridge20_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "ridge leprechaun",
-    "ridge",
-    "leprechaun",
-    "r",
-    "l"
-  ]
-}
diff --git a/world/npcs/sabretoothboar.json b/world/npcs/sabretoothboar.json
deleted file mode 100644
index 7d25df1b9b3ac2b05585f395d6970b6618071346..0000000000000000000000000000000000000000
--- a/world/npcs/sabretoothboar.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "sabretooth boar",
-  "colorName": "sabretooth \u001B[1m\u001B[35mboar\u001B[0m",
-  "dieMessage": "the sabretooth \u001B[1m\u001B[35mboar\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 25000000,
-    "lootGoldMax": 28000000,
-    "lootItems": [73]
-  },
-  "roamAreas": [
-    "bloodridge12_zone",
-    "bloodridge13_zone"
-  ],
-  "stats": {
-    "agile": 7000,
-    "aim": 9000,
-    "armorRating": 47000,
-    "currentHealth": 2000000,
-    "currentMana": 1200000,
-    "experience": 12000000,
-    "maxHealth": 2500000,
-    "maxMana": 800000,
-    "meleSkill": 70000,
-    "numberOfWeaponRolls": 20,
-    "strength": 90000,
-    "weaponRatingMax": 105000,
-    "weaponRatingMin": 40000,
-    "willPower": 30000
-  },
-  "spawnAreas": {
-    "bloodridge12_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge13_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "sabretooth boar",
-    "s",
-    "b",
-    "boar",
-    "sabretooth"
-  ]
-}
diff --git a/world/npcs/sandsquonk.json b/world/npcs/sandsquonk.json
deleted file mode 100644
index fb280e25dca2759aa2f8d60b22c36094f10ce043..0000000000000000000000000000000000000000
--- a/world/npcs/sandsquonk.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "name": "sand squonk",
-  "colorName": "sand \u001B[1m\u001B[35msquonk\u001B[0m",
-  "dieMessage": "the sand \u001B[1m\u001B[35msquonk\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 104000000000,
-    "lootGoldMax": 124000000000,
-    "lootItems": [152]
-  },
-  "roamAreas": [
-    "bloodridge18_zone",
-    "bloodridge19_zone"
-  ],
-  "stats": {
-    "agile": 19200000,
-    "aim": 19002000,
-    "armorRating": 84000000,
-    "currentHealth": 4400000000,
-    "currentMana": 2600000000,
-    "experience": 22000000000,
-    "maxHealth": 4400000000,
-    "maxMana": 1400000000,
-    "meleSkill": 208000000,
-    "numberOfWeaponRolls": 8000,
-    "strength": 182000000,
-    "weaponRatingMax": 334000000,
-    "weaponRatingMin": 210000000,
-    "willPower": 196000000
-  },
-  "spawnAreas": {
-    "bloodridge18_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    },
-    "bloodridge19_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    }
-  },
-  "validTriggers": [
-    "sand squonk",
-    "sand",
-    "squonk",
-    "s"
-  ]
-}
diff --git a/world/npcs/scaleddeathcrawler.json b/world/npcs/scaleddeathcrawler.json
deleted file mode 100755
index 3bf3fb0f740c9e689e6ff965a1e17a7a762febc6..0000000000000000000000000000000000000000
--- a/world/npcs/scaleddeathcrawler.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "scaled deathcrawler",
-  "colorName": "scaled \u001B[1m\u001B[35mdeathcrawler\u001B[0m",
-  "dieMessage": "a scaled \u001B[1m\u001B[35mdeathcrawler\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 150,
-    "lootGoldMax": 300,
-    "lootItems": [37]
-  },
-  "roamAreas": [
-    "north10_zone",
-    "north11_zone"
-  ],
-  "stats": {
-    "agile": 750,
-    "aim": 32,
-    "armorRating": 30,
-    "currentHealth": 4000,
-    "currentMana": 100,
-    "experience": 5600,
-    "maxHealth": 4000,
-    "maxMana": 100,
-    "meleSkill": 57,
-    "numberOfWeaponRolls": 1,
-    "strength": 1000,
-    "weaponRatingMax": 240,
-    "weaponRatingMin": 140,
-    "willPower": 9
-  },
-  "spawnAreas": {
-    "north10_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 20
-    }, 
-    "north11_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "scaled",
-    "s",
-    "scaled deathcrawler",
-    "deathcrawler",
-    "d"
-  ]
-}
diff --git a/world/npcs/scoffin.json b/world/npcs/scoffin.json
deleted file mode 100644
index 18a44a9c2e77a10570a554d3dd4311029b0351ee..0000000000000000000000000000000000000000
--- a/world/npcs/scoffin.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "scoffin",
-  "colorName": "\u001B[1m\u001B[35mscoffin\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mscoffin\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 100000000,
-    "lootGoldMax": 140000000,
-    "lootItems": [82]
-  },
-  "roamAreas": [
-    "tisland8_zone",
-    "tisland9_zone"
-  ],
-  "stats": {
-    "agile": 32000,
-    "aim": 40000,
-    "armorRating": 190000,
-    "currentHealth": 7500000,
-    "currentMana": 4000000,
-    "experience": 55000000,
-    "maxHealth": 8500000,
-    "maxMana": 3000000,
-    "meleSkill": 320000,
-    "numberOfWeaponRolls": 30,
-    "strength": 330000,
-    "weaponRatingMax": 500000,
-    "weaponRatingMin": 400000,
-    "willPower": 150000
-  },
-  "spawnAreas": {
-    "tisland8_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "tisland9_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "scoffin",
-    "s"
-  ]
-}
diff --git a/world/npcs/shadowminotaur.json b/world/npcs/shadowminotaur.json
deleted file mode 100644
index 47cfeaa9b1691b7631536dfed64eb3b42210a897..0000000000000000000000000000000000000000
--- a/world/npcs/shadowminotaur.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "shadow minotaur",
-  "colorName": "shadow \u001B[1m\u001B[35mminotaur\u001B[0m",
-  "dieMessage": "a shadow \u001B[1m\u001B[35mminotaur\u001B[0m lets out a blood curdling scream as it collapses and dies.",
-  "loot": {
-    "lootGoldMin": 2000000,
-    "lootGoldMax": 2500000,
-    "lootItems": [63]
-  },
-  "roamAreas": [
-    "tisland6_zone",
-    "tisland7_zone"
-  ],
-  "stats": {
-    "agile": 2100,
-    "aim": 2100,
-    "armorRating": 9000,
-    "currentHealth": 900000,
-    "currentMana": 900000,
-    "experience": 2200000,
-    "maxHealth": 900000,
-    "maxMana": 900000,
-    "meleSkill": 12000,
-    "numberOfWeaponRolls": 15,
-    "strength": 15800,
-    "weaponRatingMax": 18000,
-    "weaponRatingMin": 7000,
-    "willPower": 12000
-  },
-  "spawnAreas": {
-    "tisland6_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 4
-    }, 
-    "tisland7_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }  
-  },
-  "validTriggers": [
-    "shadow minotaur",
-    "shadow",
-    "minotaur",
-    "s",
-    "m"
-  ]
-}
diff --git a/world/npcs/silverwendigo.json b/world/npcs/silverwendigo.json
deleted file mode 100644
index f45d239d9fe7c54302c1ae08f2413147235e7142..0000000000000000000000000000000000000000
--- a/world/npcs/silverwendigo.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "silver wendigo",
-  "colorName": "silver \u001B[1m\u001B[35mwendigo\u001B[0m",
-  "dieMessage": "a silver \u001B[1m\u001B[35mwendigo\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 2000000,
-    "lootGoldMax": 2500000,
-    "lootItems": [66]
-  },
-  "roamAreas": [
-    "north12_zone",
-    "north13_zone"
-  ],
-  "stats": {
-    "agile": 140,
-    "aim": 140,
-    "armorRating": 1000,
-    "currentHealth": 300000,
-    "currentMana": 200,
-    "experience": 1800000,
-    "maxHealth": 300000,
-    "maxMana": 200,
-    "meleSkill": 800,
-    "numberOfWeaponRolls": 5,
-    "strength": 13000,
-    "weaponRatingMax": 70000,
-    "weaponRatingMin": 40000,
-    "willPower": 32
-  },
-  "spawnAreas": {
-    "north12_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 3
-    }, 
-    "north13_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 2
-    } 
-  },
-  "validTriggers": [
-    "silver wendigo",
-    "s",
-    "silver",
-    "w",
-    "wendigo"
-  ]
-}
diff --git a/world/npcs/stealthpanther.json b/world/npcs/stealthpanther.json
deleted file mode 100755
index 74188765621b410a6865381d6e9656fbced613ae..0000000000000000000000000000000000000000
--- a/world/npcs/stealthpanther.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "stealth panther",
-  "colorName": "stealth \u001B[1m\u001B[35mpanther\u001B[0m",
-  "dieMessage": "a stealth \u001B[1m\u001B[35mpanther\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 16,
-    "lootGoldMax": 32,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "north5_zone",
-    "north6_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 4,
-    "armorRating": 11,
-    "currentHealth": 500,
-    "currentMana": 300,
-    "experience": 510,
-    "maxHealth": 500,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 1,
-    "strength": 23,
-    "weaponRatingMax": 22,
-    "weaponRatingMin": 12,
-    "willPower": 5
-  },
-  "spawnAreas": {
-    "north5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }, 
-    "north6_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "s",
-    "stealth panther",
-    "panther",
-    "stealth",
-    "p"
-  ]
-}
diff --git a/world/npcs/stonegiant.json b/world/npcs/stonegiant.json
deleted file mode 100755
index 243d557c7c7b90902bb85371331e9fc04954f367..0000000000000000000000000000000000000000
--- a/world/npcs/stonegiant.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "stone giant",
-  "colorName": "stone \u001B[1m\u001B[35mgiant\u001B[0m",
-  "dieMessage": "a stone \u001B[1m\u001B[35mgiant\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 55,
-    "lootGoldMax": 69,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "tisland4_zone",
-    "tisland5_zone"
-  ],
-  "stats": {
-    "agile": 5,
-    "aim": 4,
-    "armorRating": 30,
-    "currentHealth": 700,
-    "currentMana": 100,
-    "experience": 1350,
-    "maxHealth": 700,
-    "maxMana": 100,
-    "meleSkill": 8,
-    "numberOfWeaponRolls": 2,
-    "strength": 50,
-    "weaponRatingMax": 35,
-    "weaponRatingMin": 25,
-    "willPower": 9
-  },
-  "spawnAreas": {
-    "tisland4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "tisland5_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "stone",
-    "s",
-    "stone giant",
-    "giant",
-    "g"
-  ]
-}
diff --git a/world/npcs/streethustler.json b/world/npcs/streethustler.json
deleted file mode 100755
index 8838c4658fe8912a5225478a00208c7d12b0852e..0000000000000000000000000000000000000000
--- a/world/npcs/streethustler.json
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-  "name": "street hustler",
-  "colorName": "street \u001B[1m\u001B[35mhustler\u001B[0m",
-  "dieMessage": "a street \u001B[1m\u001B[35mdeathcrawler\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 1,
-    "lootGoldMax": 3,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "newbie_zone"
-  ],
-  "stats": {
-    "agile": 1,
-    "aim": 1,
-    "armorRating": 5,
-    "currentHealth": 150,
-    "currentMana": 100,
-    "experience": 30,
-    "maxHealth": 150,
-    "maxMana": 100,
-    "meleSkill": 5,
-    "numberOfWeaponRolls": 1,
-    "strength": 5,
-    "weaponRatingMax": 10,
-    "weaponRatingMin": 5,
-    "willPower": 1
-  },
-  "spawnAreas": {
-    "newbie_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 5
-    }
-  },
-  "validTriggers": [
-    "hustler",
-    "street hustler",
-    "h",
-    "s"
-  ]
-}
diff --git a/world/npcs/swampbear.json b/world/npcs/swampbear.json
deleted file mode 100755
index c80ac20606a041286c8c96cb20e01f85ecd89e47..0000000000000000000000000000000000000000
--- a/world/npcs/swampbear.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "swamp bear",
-  "colorName": "swamp \u001B[1m\u001B[35mbear\u001B[0m",
-  "dieMessage": "a swamp \u001B[1m\u001B[35mbear\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 12,
-    "lootGoldMax": 24,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "north3_zone",
-    "north4_zone"
-  ],
-  "stats": {
-    "agile": 3,
-    "aim": 3,
-    "armorRating": 8,
-    "currentHealth": 300,
-    "currentMana": 300,
-    "experience": 250,
-    "maxHealth": 300,
-    "maxMana": 100,
-    "meleSkill": 6,
-    "numberOfWeaponRolls": 1,
-    "strength": 15,
-    "weaponRatingMax": 16,
-    "weaponRatingMin": 10,
-    "willPower": 3
-  },
-  "spawnAreas": {
-    "north3_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }, 
-    "north4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "s",
-    "swamp bear",
-    "swamp",
-    "bear",
-    "b"
-  ]
-}
diff --git a/world/npcs/swampberserker.json b/world/npcs/swampberserker.json
old mode 100755
new mode 100644
index bc5e8b04a13563a184c8bbccdcf46f277c0eab71..6261984a31f9153854c2a47ba15df58bdd747108
--- a/world/npcs/swampberserker.json
+++ b/world/npcs/swampberserker.json
@@ -2,10 +2,11 @@
   "name": "swamp berserker",
   "colorName": "swamp \u001B[1m\u001B[35mberserker\u001B[0m",
   "dieMessage": "a swamp \u001B[1m\u001B[35mberserker\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
+  "temperament": "passive",
   "loot": {
-    "lootGoldMin": 3,
-    "lootGoldMax": 10,
-    "lootItems": []
+    "lootGoldMin": 10,
+    "lootGoldMax": 19,
+    "lootItems": [3]
   },
   "roamAreas": [
     "north1_zone"
@@ -13,29 +14,29 @@
   "stats": {
     "agile": 1,
     "aim": 1,
-    "armorRating": 8,
-    "currentHealth": 230,
-    "currentMana": 100,
-    "experience": 250,
-    "maxHealth": 230,
-    "maxMana": 100,
-    "meleSkill": 6,
+    "armorRating": 6,
+    "currentHealth": 105,
+    "currentMana": 105,
+    "experience": 22500,
+    "maxHealth": 105,
+    "maxMana": 105,
+    "meleSkill": 16,
     "numberOfWeaponRolls": 1,
-    "strength": 11,
-    "weaponRatingMax": 13,
-    "weaponRatingMin": 10,
+    "strength": 10,
+    "weaponRatingMax": 15,
+    "weaponRatingMin": 9,
     "willPower": 1
   },
   "spawnAreas": {
-    "north2_zone": {
+    "north1_zone": {
       "randomChance": 100,
-      "maxPerRoom": 3,
+      "maxPerRoom": 6,
       "spawnIntervalTicks": 600,
-      "maxInstances": 12
+      "maxInstances": 24
     }
   },
   "validTriggers": [
-    "t",
+    "s",
     "swamp berserker",
     "berserker",
     "b"
diff --git a/world/npcs/taniwha.json b/world/npcs/taniwha.json
deleted file mode 100644
index 3f92517cad0d0ff804028266c958e61016ef4628..0000000000000000000000000000000000000000
--- a/world/npcs/taniwha.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-  "name": "taniwha",
-  "colorName": "\u001B[1m\u001B[35mtaniwha\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mtaniwha\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 6600000000,
-    "lootGoldMax": 7800000000,
-    "lootItems": [94, 148]
-  },
-  "roamAreas": [
-    "toft5_zone"
-  ],
-  "stats": {
-    "agile": 1200000,
-    "aim": 1200000,
-    "armorRating": 5400000,
-    "currentHealth": 270000000,
-    "currentMana": 204000000,
-    "experience": 1740000000,
-    "maxHealth": 270000000,
-    "maxMana": 96000000,
-    "meleSkill": 13800000,
-    "numberOfWeaponRolls": 485,
-    "strength": 12000000,
-    "weaponRatingMax": 21000000,
-    "weaponRatingMin": 13200000,
-    "willPower": 12000000
-  },
-  "spawnAreas": {
-    "toft5_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 3
-    }
-  },
-  "validTriggers": [
-    "taniwha",
-    "t"
-  ]
-}
diff --git a/world/npcs/tatzelwurm.json b/world/npcs/tatzelwurm.json
deleted file mode 100644
index 3951e1be381e86fcddede2db49753948fef0722d..0000000000000000000000000000000000000000
--- a/world/npcs/tatzelwurm.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
-  "name": "tatzelwurm",
-  "colorName": "\u001B[1m\u001B[35mtatzelwurm\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mtatzelwurm\u001B[0m dies in a pool of blood!",
-  "loot": {
-    "lootGoldMin": 100000,
-    "lootGoldMax": 126000,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "bloodridge8_zone",
-    "bloodridge9_zone"
-  ],
-  "stats": {
-    "agile": 100,
-    "aim": 100,
-    "armorRating": 600,
-    "currentHealth": 80000,
-    "currentMana": 80000,
-    "experience": 100000,
-    "maxHealth": 80000,
-    "maxMana": 80000,
-    "meleSkill": 600,
-    "numberOfWeaponRolls": 5,
-    "strength": 1000,
-    "weaponRatingMax": 1000,
-    "weaponRatingMin": 700,
-    "willPower": 1000
-  },
-  "spawnAreas": {
-    "bloodridge8_zone": {
-      "randomChance": 5,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge9_zone": {
-      "randomChance": 5,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "tatzelwurm",
-    "t",
-    "wurm",
-    "w"
-  ]
-}
diff --git a/world/npcs/thefirstnationalbank.json b/world/npcs/thefirstnationalbank.json
deleted file mode 100755
index bdc059f2d0adf74bdc694eec7f397bc1630be0f2..0000000000000000000000000000000000000000
--- a/world/npcs/thefirstnationalbank.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
-  "name": "first national bank",
-  "colorName": "first \u001B[1m\u001B[35mnational bank\u001B[0m",
-  "dieMessage": "the bankers cry out in despair! \u001B[1m\u001B[35mnational bank\u001B[0m drowns in its own vomit and \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 30000,
-    "lootGoldMax": 60000,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "tisland3_zone",
-    "tisland4_zone"
-  ],
-  "stats": {
-    "agile": 100,
-    "aim": 100,
-    "armorRating": 600,
-    "currentHealth": 80000,
-    "currentMana": 80000,
-    "experience": 100000,
-    "maxHealth": 80000,
-    "maxMana": 80000,
-    "meleSkill": 600,
-    "numberOfWeaponRolls": 5,
-    "strength": 1000,
-    "weaponRatingMax": 1000,
-    "weaponRatingMin": 700,
-    "willPower": 1000
-  },
-  "spawnAreas": {
-    "tisland10_zone": {
-      "randomChance": 5,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "national bank",
-    "the first national bank",
-    "bank",
-    "national"
-  ]
-}
diff --git a/world/npcs/thousandeyedspider.json b/world/npcs/thousandeyedspider.json
deleted file mode 100644
index b7aaa05eb4b4fe80481297a2946b49a1597f84c9..0000000000000000000000000000000000000000
--- a/world/npcs/thousandeyedspider.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "thousand-eyed spider",
-  "colorName": "thousand-eyed \u001B[1m\u001B[35mspider\u001B[0m",
-  "dieMessage": "the thousand-eyed \u001B[1m\u001B[35mspider\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 300000000,
-    "lootGoldMax": 400000000,
-    "lootItems": [86]
-  },
-  "roamAreas": [
-    "tisland8_zone",
-    "tisland9_zone"
-  ],
-  "stats": {
-    "agile": 84000,
-    "aim": 108000,
-    "armorRating": 500000,
-    "currentHealth": 20000000,
-    "currentMana": 12000000,
-    "experience": 160000000,
-    "maxHealth": 24000000,
-    "maxMana": 9600000,
-    "meleSkill": 840000,
-    "numberOfWeaponRolls": 60,
-    "strength": 1250000,
-    "weaponRatingMax": 1500000,
-    "weaponRatingMin": 1000000,
-    "willPower": 600000
-  },
-  "spawnAreas": {
-    "tisland8_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "tisland9_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "thousand-eyed spider",
-    "t",
-    "s",
-    "thousand-eyed",
-    "spider"
-  ]
-}
diff --git a/world/npcs/tigermonoceruses.json b/world/npcs/tigermonoceruses.json
deleted file mode 100755
index 1bb475978ffe91b7458a1fdb4efc6f8daeb822e0..0000000000000000000000000000000000000000
--- a/world/npcs/tigermonoceruses.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "tiger monocerus",
-  "colorName": "tiger \u001B[1m\u001B[35mmonocerus\u001B[0m",
-  "dieMessage": "a tiger \u001B[1m\u001B[35mmonocerus\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 20,
-    "lootGoldMax": 30,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "north8_zone",
-    "north9_zone"
-  ],
-  "stats": {
-    "agile": 6,
-    "aim": 6,
-    "armorRating": 18,
-    "currentHealth": 550,
-    "currentMana": 100,
-    "experience": 800,
-    "maxHealth": 550,
-    "maxMana": 100,
-    "meleSkill": 19,
-    "numberOfWeaponRolls": 1,
-    "strength": 34,
-    "weaponRatingMax": 36,
-    "weaponRatingMin": 20,
-    "willPower": 7
-  },
-  "spawnAreas": {
-    "north8_zone": {
-      "randomChance": 1,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "north9_zone": {
-      "randomChance": 1,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "tiger",
-    "t",
-    "tiger monocerus",
-    "monocerus",
-    "m"
-  ]
-}
diff --git a/world/npcs/treeberserker.json b/world/npcs/treeberserker.json
old mode 100755
new mode 100644
index fb4ff4f6494fc2722c337a23ec7313360289f498..0e8d951bd590f2a3133eea7e4e6e7f011b268057
--- a/world/npcs/treeberserker.json
+++ b/world/npcs/treeberserker.json
@@ -2,10 +2,11 @@
   "name": "tree berserker",
   "colorName": "tree \u001B[1m\u001B[35mberserker\u001B[0m",
   "dieMessage": "a tree \u001B[1m\u001B[35mberserker\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
+  "temperament": "passive",
   "loot": {
-    "lootGoldMin": 3,
-    "lootGoldMax": 10,
-    "lootItems": []
+    "lootGoldMin": 7,
+    "lootGoldMax": 14,
+    "lootItems": [4,6,2]
   },
   "roamAreas": [
     "north1_zone"
@@ -13,29 +14,30 @@
   "stats": {
     "agile": 1,
     "aim": 1,
-    "armorRating": 8,
-    "currentHealth": 200,
-    "currentMana": 100,
-    "experience": 150,
-    "maxHealth": 150,
-    "maxMana": 100,
-    "meleSkill": 6,
+    "armorRating": 3,
+    "currentHealth": 90,
+    "currentMana": 90,
+    "experience": 2500,
+    "maxHealth": 90,
+    "maxMana": 90,
+    "meleSkill": 12,
     "numberOfWeaponRolls": 1,
-    "strength": 5,
-    "weaponRatingMax": 13,
-    "weaponRatingMin": 8,
+    "strength": 10,
+    "weaponRatingMax": 10,
+    "weaponRatingMin": 7,
     "willPower": 1
   },
   "spawnAreas": {
     "north1_zone": {
       "randomChance": 100,
-      "maxPerRoom": 3,
+      "maxPerRoom": 6,
       "spawnIntervalTicks": 600,
-      "maxInstances": 12
+      "maxInstances": 24
     }
   },
   "validTriggers": [
     "t",
+    "tree",
     "tree berserker",
     "berserker",
     "b"
diff --git a/world/npcs/tribalalchemist.json b/world/npcs/tribalalchemist.json
deleted file mode 100644
index 94fa4dd28fbc0b8cb19124b8a35aee68317720e1..0000000000000000000000000000000000000000
--- a/world/npcs/tribalalchemist.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "tribal alchemist",
-  "colorName": "tribal \u001B[1m\u001B[35malchemist\u001B[0m",
-  "dieMessage": "the tribal \u001B[1m\u001B[35malchemist\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1100000000,
-    "lootGoldMax": 1300000000,
-    "lootItems": [111]
-  },
-  "roamAreas": [
-    "north14_zone",
-    "north15_zone"
-  ],
-  "stats": {
-    "agile": 200000,
-    "aim": 198000,
-    "armorRating": 900000,
-    "currentHealth": 45000000,
-    "currentMana": 34000000,
-    "experience": 290000000,
-    "maxHealth": 45000000,
-    "maxMana": 16000000,
-    "meleSkill": 2300000,
-    "numberOfWeaponRolls": 85,
-    "strength": 1950000,
-    "weaponRatingMax": 3500000,
-    "weaponRatingMin": 2200000,
-    "willPower": 2000000
-  },
-  "spawnAreas": {
-    "north14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "north15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "tribal alchemist",
-    "t",
-    "a",
-    "tribal",
-    "alchemist"
-  ]
-}
diff --git a/world/npcs/tribalranger.json b/world/npcs/tribalranger.json
deleted file mode 100644
index cba9a93a89443ff7c460139c6039c813945acf13..0000000000000000000000000000000000000000
--- a/world/npcs/tribalranger.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "tribal ranger",
-  "colorName": "tribal \u001B[1m\u001B[35mranger\u001B[0m",
-  "dieMessage": "the tribal \u001B[1m\u001B[35mranger\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 1000000000,
-    "lootGoldMax": 1200000000,
-    "lootItems": [109]
-  },
-  "roamAreas": [
-    "north14_zone",
-    "north15_zone"
-  ],
-  "stats": {
-    "agile": 190000,
-    "aim": 188000,
-    "armorRating": 800000,
-    "currentHealth": 42000000,
-    "currentMana": 32000000,
-    "experience": 270000000,
-    "maxHealth": 42000000,
-    "maxMana": 12000000,
-    "meleSkill": 2100000,
-    "numberOfWeaponRolls": 85,
-    "strength": 1850000,
-    "weaponRatingMax": 3200000,
-    "weaponRatingMin": 2300000,
-    "willPower": 1900000
-  },
-  "spawnAreas": {
-    "north14_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "north15_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "tribal ranger",
-    "t",
-    "r",
-    "tribal",
-    "ranger"
-  ]
-}
diff --git a/world/npcs/tunnelcobra.json b/world/npcs/tunnelcobra.json
deleted file mode 100755
index 58c252461ca89d0feb9f452608b00a78bfc03b52..0000000000000000000000000000000000000000
--- a/world/npcs/tunnelcobra.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "tunnel cobra",
-  "colorName": "tunnel \u001B[1m\u001B[35mcobra\u001B[0m",
-  "dieMessage": "a tunnel \u001B[1m\u001B[35mcobra\u001B[0m breathes his last breath in a pool of \u001B[1m\u001B[31mblood\u001B[0m",
-  "loot": {
-    "lootGoldMin": 40,
-    "lootGoldMax": 54,
-    "lootItems": []
-  },
-  "roamAreas": [
-    "tisland3_zone",
-    "tisland4_zone"
-  ],
-  "stats": {
-    "agile": 9,
-    "aim": 9,
-    "armorRating": 20,
-    "currentHealth": 300,
-    "currentMana": 100,
-    "experience": 920,
-    "maxHealth": 300,
-    "maxMana": 100,
-    "meleSkill": 18,
-    "numberOfWeaponRolls": 2,
-    "strength": 40,
-    "weaponRatingMax": 31,
-    "weaponRatingMin": 24,
-    "willPower": 16
-  },
-  "spawnAreas": {
-    "tisland4_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 6
-    }, 
-    "tisland3_zone": {
-      "randomChance": 100,
-      "maxPerRoom": 3,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 14
-    }
-  },
-  "validTriggers": [
-    "tunnel",
-    "t",
-    "tunnel cobra",
-    "cobra",
-    "c"
-  ]
-}
diff --git a/world/npcs/vinlandbard.json b/world/npcs/vinlandbard.json
deleted file mode 100644
index 40584fa916d6d7702ff431934a6190e28a729ce0..0000000000000000000000000000000000000000
--- a/world/npcs/vinlandbard.json
+++ /dev/null
@@ -1,51 +0,0 @@
-{
-  "name": "vinland bard",
-  "colorName": "vinland \u001B[1m\u001B[35mbard\u001B[0m",
-  "dieMessage": "the vinland \u001B[1m\u001B[35mbard\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 900000,
-    "lootGoldMax": 14000000,
-    "lootItems": [71]
-  },
-  "roamAreas": [
-    "western3_zone",
-    "western4_zone"
-  ],
-  "stats": {
-    "agile": 3000,
-    "aim": 4000,
-    "armorRating": 23000,
-    "currentHealth": 1800000,
-    "currentMana": 1200000,
-    "experience": 7000000,
-    "maxHealth": 1000000,
-    "maxMana": 800000,
-    "meleSkill": 15000,
-    "numberOfWeaponRolls": 15,
-    "strength": 40000,
-    "weaponRatingMax": 41000,
-    "weaponRatingMin": 23000,
-    "willPower": 16000
-  },
-  "spawnAreas": {
-    "western3_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "western4_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "vinland bard",
-    "v",
-    "b",
-    "vinland",
-    "bard"
-  ]
-}
diff --git a/world/npcs/warlock.json b/world/npcs/warlock.json
deleted file mode 100644
index 211e52bd826f4d2606c6e1a15abc5241976a2d88..0000000000000000000000000000000000000000
--- a/world/npcs/warlock.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
-  "name": "warlock",
-  "colorName": "\u001B[1m\u001B[35mwarlock\u001B[0m",
-  "dieMessage": "the \u001B[1m\u001B[35mwarlock\u001B[0m falls to the ground and convulses in death.",
-  "loot": {
-    "lootGoldMin": 21000000,
-    "lootGoldMax": 26000000,
-    "lootItems": [74]
-  },
-  "roamAreas": [
-    "bloodridge12_zone",
-    "bloodridge13_zone"
-  ],
-  "stats": {
-    "agile": 6000,
-    "aim": 8000,
-    "armorRating": 41000,
-    "currentHealth": 2000000,
-    "currentMana": 1200000,
-    "experience": 12000000,
-    "maxHealth": 2500000,
-    "maxMana": 800000,
-    "meleSkill": 70000,
-    "numberOfWeaponRolls": 20,
-    "strength": 80000,
-    "weaponRatingMax": 90000,
-    "weaponRatingMin": 40000,
-    "willPower": 30000
-  },
-  "spawnAreas": {
-    "bloodridge12_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    }, 
-    "bloodridge13_zone": {
-      "randomChance": 90,
-      "maxPerRoom": 1,
-      "spawnIntervalTicks": 600,
-      "maxInstances": 1
-    } 
-  },
-  "validTriggers": [
-    "warlock",
-    "w"
-  ]
-}
diff --git a/world/world.json b/world/world.json
index dadec1844359e64be894b443c3c6f8365df7c2e6..582ef00826e4b5b14ec8c61cae7ccd442dd250af 100644
--- a/world/world.json
+++ b/world/world.json
@@ -2931,8 +2931,8 @@
         {
           "roomId": 98,
           "floorId": 16,
-          "roomDescription": "Dried and cured meats hang from the ceiling and along the walls. A rack of sharp knives can be seen behind the counter, and leather and cloth aprons hang from several hooks on the wall.",
-          "roomTitle": "BUTCHER SHOP",
+          "roomDescription": "Dust covered books and alchemy bottles line the wall.  Everything here is for sale.",
+          "roomTitle": "Wizards Stoop",
           "roomTags": [],
           "areaNames": [
             "house_zone"
@@ -6143,7 +6143,7 @@
         {
           "roomId": 2,
           "floorId": 0,
-          "roomDescription": "Flanking the town square on its northern side, this cobblestone lane is home to a small butcher shop and a blacksmith. The simple stone buildings are covered in a layer of soot from the constant burning of coal, needed to forge the tools and weaponry required by the townspeople. To the north, the town gates can be seen in the distance.",
+          "roomDescription": "Flanking the town square on its northern side, this cobblestone lane is home to a small wizards shop and a blacksmith. The simple stone buildings are covered in a layer of soot from the constant burning of coal, needed to forge the tools and weaponry required by the townspeople. To the north, the town gates can be seen in the distance.",
           "roomTitle": "CRAIGAVON LANE NORTH",
           "roomTags": [],
           "areaNames": [
@@ -6151,7 +6151,7 @@
           ],
           "enterExitNames": {
             "66": "Blacksmith",
-            "98": "Butcher"
+            "98": "Wizard"
           },
           "notables": {}
         },