diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
index bb807241..246ca357 100644
--- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/load/DefaultMMOLoader.java
@@ -23,6 +23,9 @@ public class DefaultMMOLoader extends MMOLoader {
         if (config.getKey().equals("stat"))
             return new StatTrigger(config);
 
+        if(config.getKey().equals("unlock_slot"))
+            return new UnlockSlotTrigger(config);
+
         if (config.getKey().equals("unlock_skill"))
             return new UnlockSkillTrigger(config);
 
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
index 9ac77dc3..3fbe0b3a 100644
--- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/PlayerData.java
@@ -21,6 +21,7 @@ import net.Indyuce.mmocore.api.player.profess.SavedClassInformation;
 import net.Indyuce.mmocore.api.player.profess.Subclass;
 import net.Indyuce.mmocore.api.player.profess.resource.PlayerResource;
 import net.Indyuce.mmocore.api.player.profess.skillbinding.BoundSkillInfo;
+import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot;
 import net.Indyuce.mmocore.api.player.social.FriendRequest;
 import net.Indyuce.mmocore.api.player.stats.PlayerStats;
 import net.Indyuce.mmocore.api.quest.PlayerQuests;
@@ -122,7 +123,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
      * -Skills
      * -Skill Books
      */
-    private final Set<String> unlockedItems= new HashSet<>();
+    private final Set<String> unlockedItems = new HashSet<>();
     /**
      * Saves the amount of times the player has claimed some
      * exp item in exp tables, for both exp tables used
@@ -376,7 +377,6 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
     }
 
 
-
     /**
      * @return If the item is unlocked by the player
      * This is used for skills that can be locked & unlocked.
@@ -384,13 +384,16 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
      * Looks at the real value and thus remove the plugin identifier
      */
     public boolean hasUnlocked(Unlockable unlockable) {
-        String unlockableKey = unlockable.getUnlockNamespacedKey().substring(unlockable.getUnlockNamespacedKey().indexOf(":"));
-        return unlockedItems
-                .stream()
-                .filter(key -> key.substring(key.indexOf(":")).equals(unlockableKey))
-                .collect(Collectors.toList()).size() != 0;
+        return hasUnlocked(unlockable.getUnlockNamespacedKey());
+
     }
 
+    public boolean hasUnlocked(String unlockNamespacedKey) {
+        return unlockedItems
+                .stream()
+                .filter(key -> key.equals(unlockNamespacedKey))
+                .collect(Collectors.toList()).size() != 0;
+    }
 
     /**
      * Unlocks an item for the player. This is mainly used to unlock skills.
@@ -799,9 +802,9 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
                 final double r = Math.sin((double) t / warpTime * Math.PI);
                 for (double j = 0; j < Math.PI * 2; j += Math.PI / 4)
                     getPlayer().getLocation().getWorld().spawnParticle(Particle.REDSTONE, getPlayer().getLocation().add(
-                            Math.cos((double) 5 * t / warpTime + j) * r,
-                            (double) 2 * t / warpTime,
-                            Math.sin((double) 5 * t / warpTime + j) * r),
+                                    Math.cos((double) 5 * t / warpTime + j) * r,
+                                    (double) 2 * t / warpTime,
+                                    Math.sin((double) 5 * t / warpTime + j) * r),
                             1, new Particle.DustOptions(Color.PURPLE, 1.25f));
             }
         }.runTaskTimer(MMOCore.plugin, 0, 1);
@@ -830,7 +833,8 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
      *                         If it's null, no hologram will be displayed
      * @param splitExp         Should the exp be split among party members
      */
-    public void giveExperience(double value, @NotNull EXPSource source, @Nullable Location hologramLocation, boolean splitExp) {
+    public void giveExperience(double value, @NotNull EXPSource source, @Nullable Location hologramLocation,
+                               boolean splitExp) {
         if (value <= 0) {
             experience = Math.max(0, experience + value);
             return;
@@ -1172,7 +1176,14 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
         profess.getSkills()
                 .stream()
                 .filter(ClassSkill::isUnlockedByDefault)
-                .forEach(skill ->unlock(skill.getSkill()));
+                .forEach(skill -> unlock(skill.getSkill()));
+
+        //Loads the classUnlockedSlots
+        profess.getSlots()
+                .stream()
+                .filter(SkillSlot::isUnlockedByDefault)
+                .forEach(this::unlock);
+
     }
 
     public boolean hasSkillBound(int slot) {
@@ -1204,7 +1215,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
         if (slot >= 0) {
             //We apply the skill buffs associated with the slot to the skill.
             profess.getSkillSlot(slot).getSkillBuffTriggers().forEach(skillBuffTrigger ->
-                    skillBuffTrigger.apply(this,skill.getSkill().getHandler().getId()));
+                    skillBuffTrigger.apply(this, skill.getSkill().getHandler().getId()));
 
 
             if (skill.getSkill().getTrigger().isPassive()) {
@@ -1220,7 +1231,7 @@ public class PlayerData extends OfflinePlayerData implements Closable, Experienc
     public void unbindSkill(int slot) {
         //We remove the skill buffs associated with the slot from the skill that is .
         profess.getSkillSlot(slot).getSkillBuffTriggers().forEach(skillBuffTrigger ->
-                skillBuffTrigger.remove(this,boundSkills.get(slot).getClassSkill().getSkill().getHandler().getId()));
+                skillBuffTrigger.remove(this, boundSkills.get(slot).getClassSkill().getSkill().getHandler().getId()));
 
         BoundSkillInfo boundSkillInfo = boundSkills.remove(slot);
         boundSkillInfo.unbind();
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
index 0fb0070b..8e0d2688 100644
--- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/PlayerClass.java
@@ -15,6 +15,7 @@ import io.lumine.mythic.lib.skill.Skill;
 import io.lumine.mythic.lib.skill.handler.MythicLibSkillHandler;
 import io.lumine.mythic.lib.skill.trigger.TriggerType;
 import io.lumine.mythic.lib.version.VersionMaterial;
+import jdk.jshell.execution.Util;
 import net.Indyuce.mmocore.MMOCore;
 import net.Indyuce.mmocore.api.player.PlayerData;
 import net.Indyuce.mmocore.api.player.profess.event.EventTrigger;
@@ -39,6 +40,7 @@ import org.apache.commons.lang.Validate;
 import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.Particle;
+import org.bukkit.Utility;
 import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.inventory.ItemStack;
@@ -105,9 +107,11 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
                 throw new IllegalArgumentException("Could not apply playerhead texture: " + exception.getMessage());
             }
         Validate.isTrue(config.isConfigurationSection("skill-slots"), "You must define the skills-slots for class " + id);
-        for (String key : config.getConfigurationSection("skill-slots").getKeys(false)) {
-            SkillSlot skillSlot = new SkillSlot(config.getConfigurationSection("skill-slots." + key));
-            skillSlots.put(skillSlot.getSlot(), skillSlot);
+        for (int i = 1; i < MMOCore.plugin.configManager.maxSlots + 1; i++) {
+            if (config.contains("skill-slots." + i))
+                skillSlots.put(i, new SkillSlot(config.getConfigurationSection("skill-slots." + i)));
+            else
+                skillSlots.put(i, new SkillSlot(i, 0, "true", "&eSkill Slot " + MMOCoreUtils.intToRoman(i), new ArrayList<>(), false, new ArrayList<>()));
         }
         for (String string : config.getStringList("display.lore"))
             description.add(ChatColor.GRAY + MythicLib.plugin.parseColors(string));
@@ -185,7 +189,7 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
             if (config.contains("skills." + key))
                 skills.put(key, new ClassSkill(registered, config.getConfigurationSection("skills." + key)));
             else
-                skills.put(key, new ClassSkill(registered, 1, 1,false));
+                skills.put(key, new ClassSkill(registered, 1, 1, false));
         }
 
         castParticle = config.contains("cast-particle") ? new CastingParticle(config.getConfigurationSection("cast-particle")) : null;
@@ -428,6 +432,10 @@ public class PlayerClass extends PostLoadObject implements ExperienceObject {
         return skillSlots.get(slot);
     }
 
+    public Collection<SkillSlot> getSlots() {
+        return skillSlots.values();
+    }
+
     public ClassSkill getSkill(RegisteredSkill skill) {
         return getSkill(skill.getHandler().getId());
     }
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java
index 91e58797..dd9f7ecc 100644
--- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/player/profess/skillbinding/SkillSlot.java
@@ -2,31 +2,36 @@ package net.Indyuce.mmocore.api.player.profess.skillbinding;
 
 import io.lumine.mythic.lib.api.MMOLineConfig;
 import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.Unlockable;
 import net.Indyuce.mmocore.api.quest.trigger.SkillBuffTrigger;
 import net.Indyuce.mmocore.skill.ClassSkill;
 import org.bukkit.Material;
 import org.bukkit.configuration.ConfigurationSection;
+
 import java.util.ArrayList;
 import java.util.List;
 
-public class SkillSlot {
+public class SkillSlot implements Unlockable {
     private final int slot, modelData;
     private final String formula;
     private final String name;
     private final List<String> lore;
 
+    private final boolean isUnlockedByDefault;
+
     private final List<SkillBuffTrigger> skillBuffTriggers;
 
     private Material item;
 
-    public SkillSlot(int slot, int modelData, String formula, String name, List<String> lore, List<SkillBuffTrigger> skillBuffTriggers, Material item) {
+    public SkillSlot(int slot, int modelData, String formula, String name, List<String> lore, boolean isUnlockedByDefault, List<SkillBuffTrigger> skillBuffTriggers) {
         this.slot = slot;
         this.modelData = modelData;
         this.formula = formula;
         this.name = name;
         this.lore = lore;
+        this.isUnlockedByDefault = isUnlockedByDefault;
         this.skillBuffTriggers = skillBuffTriggers;
-        this.item = item;
     }
 
     public SkillSlot(ConfigurationSection section) {
@@ -37,10 +42,11 @@ public class SkillSlot {
         if (section.contains("item"))
             this.item = Material.valueOf(section.getString("item"));
         this.modelData = section.getInt("model-data", 0);
-        skillBuffTriggers= new ArrayList<>();
-        if(section.contains("skill-buffs"))
-            for(String skillBuff:section.getStringList("skill-buffs"))
-                if(skillBuff.startsWith("skill_buff")){
+        isUnlockedByDefault = section.getBoolean("unlocked-by-default", true);
+        skillBuffTriggers = new ArrayList<>();
+        if (section.contains("skill-buffs"))
+            for (String skillBuff : section.getStringList("skill-buffs"))
+                if (skillBuff.startsWith("skill_buff")) {
                     skillBuffTriggers.add((SkillBuffTrigger) MMOCore.plugin.loadManager.loadTrigger(new MMOLineConfig(skillBuff)));
                 }
     }
@@ -69,6 +75,10 @@ public class SkillSlot {
         return modelData;
     }
 
+    public boolean isUnlockedByDefault() {
+        return isUnlockedByDefault;
+    }
+
     public List<SkillBuffTrigger> getSkillBuffTriggers() {
         return skillBuffTriggers;
     }
@@ -76,4 +86,24 @@ public class SkillSlot {
     public boolean canPlaceSkill(ClassSkill classSkill) {
         return classSkill.getSkill().matchesFormula(formula);
     }
+
+    @Override
+    public String getUnlockNamespacedKey() {
+        return "slot:"+slot;
+    }
+
+    /**
+     * If we lock a slot that had a skill bound
+     * to it we first unbind the attached skill.
+     */
+    @Override
+    public void whenLocked(PlayerData playerData) {
+        if(playerData.hasSkillBound(slot))
+            playerData.unbindSkill(slot);
+    }
+
+    @Override
+    public void whenUnlocked(PlayerData playerData) {
+
+    }
 }
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/UnlockSlotTrigger.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/UnlockSlotTrigger.java
new file mode 100644
index 00000000..9c87c042
--- /dev/null
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/api/quest/trigger/UnlockSlotTrigger.java
@@ -0,0 +1,37 @@
+package net.Indyuce.mmocore.api.quest.trigger;
+
+import io.lumine.mythic.lib.api.MMOLineConfig;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot;
+import net.Indyuce.mmocore.api.quest.trigger.api.Removable;
+import net.Indyuce.mmocore.skill.RegisteredSkill;
+import org.apache.commons.lang.Validate;
+
+import java.util.Objects;
+
+
+public class UnlockSlotTrigger extends Trigger implements Removable {
+    private final int slot;
+
+    public UnlockSlotTrigger(MMOLineConfig config) {
+        super(config);
+        config.validateKeys("slot");
+        slot = Integer.parseInt("slot");
+        Validate.isTrue(slot > 0 && slot <= MMOCore.plugin.configManager.maxSlots, "The slot should be between 1 and " + MMOCore.plugin.configManager.maxSlots);
+    }
+
+    @Override
+    public void apply(PlayerData player) {
+        SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
+        if (!player.hasUnlocked(skillSlot))
+            player.unlock(skillSlot);
+    }
+
+    @Override
+    public void remove(PlayerData player) {
+        SkillSlot skillSlot = player.getProfess().getSkillSlot(slot);
+        if (player.hasUnlocked(skillSlot))
+            player.lock(skillSlot);
+    }
+}
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SlotCommandTreeNode.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SlotCommandTreeNode.java
new file mode 100644
index 00000000..38c2c852
--- /dev/null
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/command/rpg/admin/SlotCommandTreeNode.java
@@ -0,0 +1,79 @@
+package net.Indyuce.mmocore.command.rpg.admin;
+
+import io.lumine.mythic.lib.command.api.CommandTreeNode;
+import io.lumine.mythic.lib.command.api.Parameter;
+import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.player.PlayerData;
+import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot;
+import net.Indyuce.mmocore.command.api.CommandVerbose;
+import net.Indyuce.mmocore.skill.ClassSkill;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+
+public class SlotCommandTreeNode extends CommandTreeNode {
+    public SlotCommandTreeNode(CommandTreeNode parent) {
+        super(parent, "skill");
+        addChild(new LockSlotCommandTreeNode(this, "lock", true));
+        addChild(new LockSlotCommandTreeNode(this, "unlock", false));
+    }
+
+    public class LockSlotCommandTreeNode extends CommandTreeNode {
+        private final boolean lock;
+
+        public LockSlotCommandTreeNode(CommandTreeNode parent, String id, boolean lock) {
+            super(parent, id);
+            this.lock = lock;
+            addParameter(Parameter.PLAYER);
+            addParameter(Parameter.AMOUNT);
+        }
+
+        @Override
+        public CommandResult execute(CommandSender sender, String[] args) {
+            if (args.length < 5)
+                return CommandResult.THROW_USAGE;
+            Player player = Bukkit.getPlayer(args[3]);
+            if (player == null) {
+                sender.sendMessage(ChatColor.RED + "Could not find the player called " + args[3] + ".");
+                return CommandResult.FAILURE;
+            }
+            PlayerData playerData = PlayerData.get(player);
+            int slot;
+            try {
+                slot = Integer.parseInt(args[4]);
+            } catch (NumberFormatException e) {
+                sender.sendMessage(ChatColor.RED + args[4] + " is not a valid number.");
+                return CommandResult.FAILURE;
+            }
+            if (slot <= 0) {
+                sender.sendMessage(ChatColor.RED + "The slot can't be negative.");
+                return CommandResult.FAILURE;
+            }
+            SkillSlot skillSlot=playerData.getProfess().getSkillSlot(slot);
+            if (lock) {
+                if (!playerData.hasUnlocked(skillSlot)) {
+                    CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill slot " + skillSlot.getName() + " is already locked" + " for " + player.getName());
+                    return CommandResult.SUCCESS;
+                }
+                playerData.lock(skillSlot);
+
+            } else {
+                if (playerData.hasUnlocked(skillSlot)) {
+                    CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.RED + "The skill slot " + skillSlot.getName() + " is already unlocked" + " for " + player.getName());
+                    return CommandResult.SUCCESS;
+                }
+                playerData.unlock(skillSlot);
+            }
+            CommandVerbose.verbose(sender, CommandVerbose.CommandType.SKILL, ChatColor.GOLD + "The skill slot " + skillSlot.getName() + " is now " + (lock ? "locked" : "unlocked" + " for " + player.getName()));
+            return CommandResult.SUCCESS;
+        }
+    }
+
+
+    @Override
+    public CommandResult execute(CommandSender sender, String[] args) {
+        return CommandResult.THROW_USAGE;
+    }
+}
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java
index 575ad2f4..b5cbb113 100644
--- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/gui/SkillList.java
@@ -4,6 +4,7 @@ import io.lumine.mythic.lib.MythicLib;
 import io.lumine.mythic.lib.api.item.ItemTag;
 import io.lumine.mythic.lib.api.item.NBTItem;
 import net.Indyuce.mmocore.MMOCore;
+import net.Indyuce.mmocore.api.SoundEvent;
 import net.Indyuce.mmocore.api.player.PlayerData;
 import net.Indyuce.mmocore.api.player.profess.skillbinding.SkillSlot;
 import net.Indyuce.mmocore.api.util.MMOCoreUtils;
@@ -15,9 +16,7 @@ import net.Indyuce.mmocore.gui.api.item.Placeholders;
 import net.Indyuce.mmocore.gui.api.item.SimplePlaceholderItem;
 import net.Indyuce.mmocore.skill.ClassSkill;
 import net.Indyuce.mmocore.skill.RegisteredSkill;
-import net.Indyuce.mmocore.api.SoundEvent;
 import org.apache.commons.lang.Validate;
-import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
 import org.bukkit.Material;
 import org.bukkit.Sound;
@@ -66,49 +65,7 @@ public class SkillList extends EditableInventory {
         }
 
         if (function.equals("slot"))
-            return new SlotItem(config) {
-                @Override
-                public ItemStack display(SkillViewerInventory inv, int n) {
-                    if (!inv.getPlayerData().getProfess().hasSlot(n + 1)) {
-                        return new ItemStack(Material.AIR);
-                    }
-                    SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1);
-                    ItemStack item = super.display(inv, n);
-                    if (!inv.getPlayerData().hasSkillBound(n + 1)) {
-                        //If there is an item filled in the slot config it shows it, else shows the default item.
-                        Material material = skillSlot.hasItem() ? skillSlot.getItem() : super.emptyMaterial;
-                        int customModelData = skillSlot.hasItem() ? skillSlot.getModelData() : super.emptyCMD;
-                        item.setType(material);
-                        ItemMeta meta = item.getItemMeta();
-                        meta.setDisplayName(MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), skillSlot.getName()));
-                        List<String> lore = skillSlot.getLore()
-                                .stream()
-                                .map(str -> MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), str))
-                                .collect(Collectors.toList());
-                        meta.setLore(lore);
-                        if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) {
-                            meta.setCustomModelData(customModelData);
-                        }
-                        item.setItemMeta(meta);
-
-                    }
-
-                    return item;
-                }
-
-                /**
-                 * This should only be called when there is a skill bound.
-                 */
-                @Override
-                public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
-                    Placeholders holders = super.getPlaceholders(inv, n);
-                    String none = MythicLib.plugin.parseColors(config.getString("no-skill"));
-                    RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n + 1) ? inv.getPlayerData().getBoundSkill(n + 1).getSkill() : null;
-                    holders.register("skill", skill == null ? none : skill.getName());
-                    return holders;
-                }
-
-            };
+            return new SlotItem(config);
 
         if (function.equals("previous"))
             return new SimplePlaceholderItem<SkillViewerInventory>(config) {
@@ -200,6 +157,39 @@ public class SkillList extends EditableInventory {
             emptyCMD = config.getInt("empty-custom-model-data", getModelData());
         }
 
+
+        @Override
+        public ItemStack display(SkillViewerInventory inv, int n) {
+            if (!inv.getPlayerData().hasUnlocked("slot:" + n)) {
+                return new ItemStack(Material.AIR);
+            }
+            SkillSlot skillSlot = inv.getPlayerData().getProfess().getSkillSlot(n + 1);
+            ItemStack item = super.display(inv, n);
+            if (!inv.getPlayerData().hasSkillBound(n + 1)) {
+                //If there is an item filled in the slot config it shows it, else shows the default item.
+                Material material = skillSlot.hasItem() ? skillSlot.getItem() : emptyMaterial;
+                int customModelData = skillSlot.hasItem() ? skillSlot.getModelData() : emptyCMD;
+                item.setType(material);
+                ItemMeta meta = item.getItemMeta();
+                meta.setDisplayName(MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), skillSlot.getName()));
+                List<String> lore = skillSlot.getLore()
+                        .stream()
+                        .map(str -> MMOCore.plugin.placeholderParser.parse(inv.getPlayerData().getPlayer(), str))
+                        .collect(Collectors.toList());
+                meta.setLore(lore);
+                if (MythicLib.plugin.getVersion().isStrictlyHigher(1, 13)) {
+                    meta.setCustomModelData(customModelData);
+                }
+                item.setItemMeta(meta);
+
+            }
+
+            return item;
+        }
+
+        /**
+         * This should only be called when there is a skill bound.
+         */
         @Override
         public Placeholders getPlaceholders(SkillViewerInventory inv, int n) {
             RegisteredSkill selected = inv.selected.getSkill();
@@ -209,10 +199,12 @@ public class SkillList extends EditableInventory {
             holders.register("index", "" + (n + 1));
             holders.register("slot", MMOCoreUtils.intToRoman(n + 1));
             holders.register("selected", selected == null ? none : selected.getName());
-
+            RegisteredSkill skill = inv.getPlayerData().hasSkillBound(n + 1) ? inv.getPlayerData().getBoundSkill(n + 1).getSkill() : null;
+            holders.register("skill", skill == null ? none : skill.getName());
             return holders;
         }
 
+
         @Override
         public boolean hasDifferentDisplay() {
             return true;
@@ -317,7 +309,9 @@ public class SkillList extends EditableInventory {
         private final List<Integer> skillSlots;
         private final List<Integer> slotSlots;
 
-        //The skill the player Selected
+        /**
+         * The skill the player Selected
+         */
         private ClassSkill selected;
         private int page = 0;
 
@@ -329,6 +323,7 @@ public class SkillList extends EditableInventory {
                     .sorted(Comparator.comparingInt(ClassSkill::getUnlockLevel))
                     .collect(Collectors.toList());
             skillSlots = getEditable().getByFunction("skill").getSlots();
+
             Validate.notNull(getEditable().getByFunction("slot"), "Your skill GUI config file is out-of-date, please regenerate it.");
             slotSlots = getEditable().getByFunction("slot").getSlots();
             selected = skills.get(page * skillSlots.size());
diff --git a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
index 26e3911c..d4d93cd8 100644
--- a/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
+++ b/MMOCore-API/src/main/java/net/Indyuce/mmocore/manager/ConfigManager.java
@@ -34,7 +34,7 @@ public class ConfigManager {
     public long combatLogTimer, lootChestExpireTime, lootChestPlayerCooldown, globalSkillCooldown;
     public double lootChestsChanceWeight, dropItemsChanceWeight, fishingDropsChanceWeight, partyMaxExpSplitRange, pvpModeToggleOnCooldown, pvpModeToggleOffCooldown, pvpModeCombatCooldown,
             pvpModeCombatTimeout, pvpModeInvulnerabilityTimeRegionChange, pvpModeInvulnerabilityTimeCommand, pvpModeRegionEnterCooldown, pvpModeRegionLeaveCooldown;
-    public int maxPartyLevelDifference, maxBoundActiveSkills, maxBoundPassiveSkills, minCombatLevel, maxCombatLevelDifference;
+    public int maxPartyLevelDifference, maxSlots, minCombatLevel, maxCombatLevelDifference;
     public final List<EntityDamageEvent.DamageCause> combatLogDamageCauses = new ArrayList<>();
 
     private final FileConfiguration messages;
@@ -157,8 +157,7 @@ public class ConfigManager {
         canCreativeCast = MMOCore.plugin.getConfig().getBoolean("can-creative-cast");
         cobbleGeneratorXP = MMOCore.plugin.getConfig().getBoolean("should-cobblestone-generators-give-exp");
         saveDefaultClassInfo = MMOCore.plugin.getConfig().getBoolean("save-default-class-info");
-        maxBoundActiveSkills = MMOCore.plugin.getConfig().getInt("max-bound-active-skills", 6);
-        maxBoundPassiveSkills = MMOCore.plugin.getConfig().getInt("max-bound-passive-skills", 3);
+        maxSlots = MMOCore.plugin.getConfig().getInt("max-slots");
         overrideVanillaExp = MMOCore.plugin.getConfig().getBoolean("override-vanilla-exp");
     }
 
diff --git a/MMOCore-Dist/src/main/resources/config.yml b/MMOCore-Dist/src/main/resources/config.yml
index a796b374..d59b2c26 100644
--- a/MMOCore-Dist/src/main/resources/config.yml
+++ b/MMOCore-Dist/src/main/resources/config.yml
@@ -197,16 +197,14 @@ death-exp-loss:
   # Percentage of current EXP you lose when dying.
   percent: 30
 
-#Default max bound active and passive skills.
-#These value can be modified for each class in the class yml.
-max-bound-active-skills: 6
+#Maximum number of slot. This means that you can't unlock a slot greater than max-slots. (The slot count starts at 1 & end at max-slots).
+max-slots: 10
 
 #If you want players to bound their passive skills.
 #If false, all the passive skills unlocked will be active
 #Also set max-bound-passive-skills to 0 if seting passive-skill-need-bound to false.
 passive-skill-need-bound: true
 
-max-bound-passive-skills: 3
 
 # Fun extra RPG feature that switches the player's hotbar with
 # the 9 lower row items of his inventory. This allows the player