diff --git a/src/main/java/com/comandante/creeper/ConfigureNpc.java b/src/main/java/com/comandante/creeper/ConfigureNpc.java
index ea8febce132b3f6268e82445ad01873cac0a9a6a..6d93d315850b15847d1eebacfcce43bb05d64325 100755
--- 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;
@@ -72,6 +71,7 @@ public class ConfigureNpc {
         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.LIGHTNING_SPELLBOOKNG, 1100));
 
         Blacksmith blacksmith = new Blacksmith(gameManager, new Loot(18, 26, Sets.<ItemType>newHashSet()), blacksmithItems);
         gameManager.getRoomManager().addMerchant(66, blacksmith);
@@ -96,6 +96,6 @@ public class ConfigureNpc {
         gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE2_ZONE, marijuanaForageBuilder);
         gameManager.getForageManager().addForageToArea(Area.BLOODRIDGE1_ZONE, marijuanaForageBuilder);
 
-        SpellRegistry.addSpell(new LightningSpell(gameManager));
+        SpellTriggerRegistry.addSpell(new LightningSpell(gameManager));
     }
 }
diff --git a/src/main/java/com/comandante/creeper/Items/ItemType.java b/src/main/java/com/comandante/creeper/Items/ItemType.java
index baf315a9bf3f08339ad1483fdbfd987c65057178..38d9d96e40ca58ca5fac051850933b7aeca1935b 100755
--- a/src/main/java/com/comandante/creeper/Items/ItemType.java
+++ b/src/main/java/com/comandante/creeper/Items/ItemType.java
@@ -145,7 +145,18 @@ public enum ItemType {
             60,
             true,
             Rarity.BASIC,
-            3000, Sets.<TimeTracker.TimeOfDay>newHashSet());
+            3000, Sets.<TimeTracker.TimeOfDay>newHashSet()),
+
+    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,
+            3000, Sets.<TimeTracker.TimeOfDay>newHashSet()),;
 
             
     private final Integer itemTypeCode;
diff --git a/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java b/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java
index 6e9871be3994e7f6a964163209fe5d14c5760e81..c8f89507e9d53921eff29b9e76b37564746f3682 100644
--- a/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java
+++ b/src/main/java/com/comandante/creeper/Items/ItemUseRegistry.java
@@ -2,6 +2,7 @@ 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.LightningSpellBookUseAction;
 import com.comandante.creeper.Items.use.ResetAllEffectsUseAction;
 import com.comandante.creeper.managers.GameManager;
 import com.comandante.creeper.player.Player;
@@ -38,6 +39,9 @@ public class ItemUseRegistry {
 
         //Marijuana
         addItemUseAction(new DefaultApplyStatsAction(ItemType.MARIJUANA, buildStats(500,500), Sets.<Effect>newHashSet()));
+
+        //Lightning Spellbook
+        addItemUseAction(new LightningSpellBookUseAction(ItemType.LIGHTNING_SPELLBOOKNG));
     }
 
     private static Stats buildStats(int health, int mana) {
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..4d3c205c1bcf24c1a29ed320b8dee48ca929f968
--- /dev/null
+++ b/src/main/java/com/comandante/creeper/Items/use/LightningSpellBookUseAction.java
@@ -0,0 +1,50 @@
+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.npc.Npc;
+import com.comandante.creeper.npc.NpcStatsChangeBuilder;
+import com.comandante.creeper.player.Player;
+import com.comandante.creeper.server.Color;
+import com.comandante.creeper.spells.Effect;
+import com.comandante.creeper.spells.LightningSpell;
+import com.comandante.creeper.stat.StatsBuilder;
+import com.comandante.creeper.world.Room;
+
+import java.text.NumberFormat;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Set;
+
+public class LightningSpellBookUseAction implements ItemUseAction {
+
+    private final ItemType itemType;
+
+    public LightningSpellBookUseAction(ItemType itemType) {
+        this.itemType = itemType;
+    }
+
+    @Override
+    public Integer getItemTypeId() {
+        return itemType.getItemTypeCode();
+    }
+
+    @Override
+    public void executeAction(GameManager gameManager, Player player, Item item) {
+        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) {
+        player.removeInventoryId(item.getItemId());
+        gameManager.getEntityManager().removeItem(item);
+    }
+
+    @Override
+    public Set<Effect> getEffects() {
+        return null;
+    }
+}
diff --git a/src/main/java/com/comandante/creeper/command/CastCommand.java b/src/main/java/com/comandante/creeper/command/CastCommand.java
index c8236f38cf651d5f7c95bdbba3af87907e73be5a..d2a688618d5ae74bf5bcc1b6f23ea4808a602461 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;
@@ -42,8 +42,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;
             }
diff --git a/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java b/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java
index b2ef99bb5c92ffecbb50271cbb3537e74f79e166..5e9e3d2ac985cafe2cef852247509c925935c8ca 100644
--- a/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java
+++ b/src/main/java/com/comandante/creeper/managers/NewUserRegistrationManager.java
@@ -63,7 +63,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]);
         playerManager.savePlayerMetadata(playerMetadata);
         e.getChannel().write("User created.\r\n");
         session.setState(CreeperSession.State.newUserRegCompleted);
diff --git a/src/main/java/com/comandante/creeper/player/Player.java b/src/main/java/com/comandante/creeper/player/Player.java
index a3ded4048fddac62355cbdb929982a320504198b..7fb1b00f930b669dd871860d2e4d43b7005524c2 100755
--- a/src/main/java/com/comandante/creeper/player/Player.java
+++ b/src/main/java/com/comandante/creeper/player/Player.java
@@ -290,8 +290,8 @@ public class Player extends CreeperEntity {
         }
     }
 
-    public void resetEffects(){
-        synchronized (interner){
+    public void resetEffects() {
+        synchronized (interner) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
             playerMetadata.resetEffects();
             gameManager.getPlayerManager().savePlayerMetadata(playerMetadata);
@@ -314,6 +314,31 @@ public class Player extends CreeperEntity {
         }
     }
 
+    public void addLearnedSpellByName(String spellName) {
+        synchronized (interner.intern(playerId)) {
+            PlayerMetadata playerMetadata = getPlayerMetadata();
+            playerMetadata.addLearnedSpellByName(spellName);
+            savePlayerMetadata(playerMetadata);
+        }
+    }
+
+    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.removeLearnedSpellByName(spellName);
+            savePlayerMetadata(playerMetadata);
+        }
+    }
+
     public void addEquipmentId(String equipmentId) {
         synchronized (interner.intern(playerId)) {
             PlayerMetadata playerMetadata = getPlayerMetadata();
@@ -936,18 +961,18 @@ 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)); 
+                    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(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)) {
@@ -956,12 +981,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());
         }
diff --git a/src/main/java/com/comandante/creeper/player/PlayerMetadata.java b/src/main/java/com/comandante/creeper/player/PlayerMetadata.java
index 44004e8ad0f3137e8a051dea1ac6b4c2288150b7..8ed7a3b16b8690e58ff8c083b1622d77a4f91554 100644
--- a/src/main/java/com/comandante/creeper/player/PlayerMetadata.java
+++ b/src/main/java/com/comandante/creeper/player/PlayerMetadata.java
@@ -24,8 +24,9 @@ public class PlayerMetadata implements Serializable {
     private List<String> effects;
     private boolean isMarkedForDelete;
     private Map<String, String> playerSettings;
+    private String[] learnedSpells;
 
-    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) {
         this.playerName = playerName;
         this.password = password;
         this.playerId = playerId;
@@ -34,6 +35,7 @@ public class PlayerMetadata implements Serializable {
         this.playerRoleSet = playerRoleSet;
         this.playerEquipment = playerEquipment;
         this.goldInBank = goldInBank;
+        this.learnedSpells = learnedSpells;
     }
 
     public PlayerMetadata(PlayerMetadata playerMetadata) {
@@ -61,6 +63,9 @@ public class PlayerMetadata implements Serializable {
         if (playerMetadata.playerSettings != null) {
             this.playerSettings = new HashMap<String, String>(playerMetadata.getPlayerSettings());
         }
+        if (playerMetadata.learnedSpells != null) {
+            this.learnedSpells = Arrays.copyOf(playerMetadata.learnedSpells, playerMetadata.learnedSpells.length);
+        }
         this.isMarkedForDelete = new Boolean(playerMetadata.isMarkedForDelete);
     }
 
@@ -101,6 +106,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 +187,10 @@ public class PlayerMetadata implements Serializable {
         return goldInBank;
     }
 
+    public String[] getLearnedSpells() {
+        return learnedSpells;
+    }
+
     protected void setGold(long amt) {
         this.gold = amt;
     }
diff --git a/src/main/java/com/comandante/creeper/spells/LightningSpell.java b/src/main/java/com/comandante/creeper/spells/LightningSpell.java
index b9fc556bf337c1cb1f70c6d188b9d2cbc3f30412..c2f5af11a67abb5e6637abbb64e7b10d5caa0bde 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}
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);
     }
+
 }