diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java
index 70602b02..731dce8c 100644
--- a/src/engine/objects/Mob.java
+++ b/src/engine/objects/Mob.java
@@ -31,6 +31,7 @@ import engine.net.client.msg.PlaceAssetMsg;
 import engine.powers.EffectsBase;
 import engine.powers.MobPowerEntry;
 import engine.server.MBServerStatics;
+import engine.util.ZoneLevel;
 import org.joda.time.DateTime;
 import org.pmw.tinylog.Logger;
 
@@ -101,6 +102,8 @@ public class Mob extends AbstractIntelligenceAgent {
     private DateTime upgradeDateTime = null;
     private boolean lootSync = false;
 
+    private String originalFirstName;
+    private String originalLastName;
 
     /**
      * No Id Constructor
@@ -129,6 +132,9 @@ public class Mob extends AbstractIntelligenceAgent {
             this.lastName = "the " + contract.getName();
         }
         clearStatic();
+
+        originalFirstName = this.firstName;
+        originalLastName = this.lastName;
     }
 
     /**
@@ -150,6 +156,9 @@ public class Mob extends AbstractIntelligenceAgent {
         this.building = building;
         initializeMob(false, false, false);
         clearStatic();
+
+        originalFirstName = this.firstName;
+        originalLastName = this.lastName;
     }
 
     /**
@@ -166,6 +175,9 @@ public class Mob extends AbstractIntelligenceAgent {
         this.BehaviourType = Enum.MobBehaviourType.Pet1;
         initializeMob(true, false, false);
         clearStatic();
+
+        originalFirstName = this.firstName;
+        originalLastName = this.lastName;
     }
 
     //SIEGE CONSTRUCTOR
@@ -180,6 +192,9 @@ public class Mob extends AbstractIntelligenceAgent {
         this.equip = new HashMap<>();
         initializeMob(false, true, isPlayerGuard);
         clearStatic();
+
+        originalFirstName = this.firstName;
+        originalLastName = this.lastName;
     }
 
     /**
@@ -288,6 +303,8 @@ public class Mob extends AbstractIntelligenceAgent {
             Logger.error("Mobile:" + this.dbID + ": " + e);
         }
 
+        originalFirstName = this.firstName;
+        originalLastName = this.lastName;
     }
 
     public static void serializeMobForClientMsgOtherPlayer(Mob mob, ByteBufferWriter writer) throws SerializationException {
@@ -1382,6 +1399,9 @@ public class Mob extends AbstractIntelligenceAgent {
 
         NPCManager.applyRuneSetEffects(this);
 
+        Zone camp = ZoneManager.findSmallestZone(this.loc);
+        this.lastName = this.originalLastName + ZoneLevel.GetNameSuffix(camp);
+
         this.recalculateStats();
         this.setHealth(this.healthMax);
 
diff --git a/src/engine/objects/Zone.java b/src/engine/objects/Zone.java
index 2fbca751..1410c0cd 100644
--- a/src/engine/objects/Zone.java
+++ b/src/engine/objects/Zone.java
@@ -18,7 +18,10 @@ import engine.math.Bounds;
 import engine.math.Vector2f;
 import engine.math.Vector3fImmutable;
 import engine.net.ByteBufferWriter;
+import engine.net.DispatchMessage;
+import engine.net.client.msg.chat.ChatSystemMsg;
 import engine.server.MBServerStatics;
+import engine.util.ZoneLevel;
 import org.pmw.tinylog.Logger;
 
 import java.sql.ResultSet;
@@ -61,7 +64,9 @@ public class Zone extends AbstractGameObject {
     //public static ArrayList<Mob> respawnQue = new ArrayList<>();
     public static final Set<Mob> respawnQue = Collections.newSetFromMap(new ConcurrentHashMap<>());
     public static long lastRespawn = 0;
+
     private int campLvl = 0;
+
     /**
      * ResultSet Constructor
      */
@@ -101,13 +106,24 @@ public class Zone extends AbstractGameObject {
 
         if (hash == null)
             setHash();
-
-
     }
 
     public void setCampLvl(int level)
     {
         this.campLvl = level;
+
+        if (this.campLvl > ZoneLevel.CampMaxLvl)
+        {
+            this.campLvl = ZoneLevel.CampMaxLvl;
+        }
+
+        if (this.campLvl > ZoneLevel.CampLvlAnnounceThreshold)
+        {
+            ChatSystemMsg chatMsg = new ChatSystemMsg(null, this.getName() + " has reached camp level " + this.campLvl + "! Will anyone contest?!");
+            chatMsg.setMessageType(2);
+            chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
+            DispatchMessage.dispatchMsgToAll(chatMsg);
+        }
     }
 
     public int getCamplvl()
diff --git a/src/engine/util/ZoneLevel.java b/src/engine/util/ZoneLevel.java
new file mode 100644
index 00000000..ccf27795
--- /dev/null
+++ b/src/engine/util/ZoneLevel.java
@@ -0,0 +1,77 @@
+package engine.util;
+
+import engine.objects.Zone;
+
+import java.util.Dictionary;
+
+public class ZoneLevel {
+
+    private static final float healthPctPerLevel = (float)0.2;
+    private static final float atrPctPerLevel = (float)0.2;
+    private static final float defPctPerLevel = (float)0.2;
+    private static final float lootPctPerLevel = (float)0.1;
+
+    public static final int CampLvlAnnounceThreshold = 5;
+    public static final int CampMaxLvl = 10;
+
+    private static final String[] nameMap =
+            {
+              "",
+              " I",
+              " II",
+              " III",
+              " IV",
+              " V",
+              " VI",
+              " VII",
+              " VIII",
+              " IX",
+              " X"
+            };
+
+    public static String GetNameSuffix(Zone zone)
+    {
+        try {
+            return nameMap[zone.getCamplvl()];
+        }
+        catch (Exception ignored)
+        {
+        }
+
+        return "";
+    }
+
+    public static float GetMaxHealthPctModifier(Zone zone)
+    {
+        return GetGenericModifier(zone, healthPctPerLevel);
+    }
+
+    public static float GetAtrPctModifier(Zone zone)
+    {
+        return GetGenericModifier(zone, atrPctPerLevel);
+    }
+
+    public static float GetDefPctModifier(Zone zone)
+    {
+        return GetGenericModifier(zone, defPctPerLevel);
+    }
+
+    public static float GetLootDropModifier(Zone zone)
+    {
+        return GetGenericModifier(zone, lootPctPerLevel);
+    }
+
+
+
+    private static float GetGenericModifier(Zone zone, float modifierPerLevel)
+    {
+        float modifier = (float)1.0;
+
+        if (zone != null)
+        {
+            modifier += zone.getCamplvl() * modifierPerLevel;
+        }
+
+        return modifier;
+    }
+}