diff --git a/src/engine/InterestManagement/Terrain.java b/src/engine/InterestManagement/Terrain.java
index 1bf98daa..2cf5eda6 100644
--- a/src/engine/InterestManagement/Terrain.java
+++ b/src/engine/InterestManagement/Terrain.java
@@ -32,12 +32,12 @@ public class Terrain {
     public Terrain(Zone zone) {
 
         this.zone = zone;
-        this.heightmap = this.zone.terrain_image;
+        this.heightmap = this.zone.template.terrain_image;
 
         // Configure PLANAR zones to use the same 16x16 pixel image
         // that all similar terrains share.  (See JSON)
 
-        if (this.zone.terrain_type.equals("PLANAR"))
+        if (this.zone.template.terrain_type.equals("PLANAR"))
             this.heightmap = 1006300;  // all 0
 
         // Load pixel data for this terrain from cache
@@ -49,8 +49,8 @@ public class Terrain {
 
         // Configure terrain based on zone properties
 
-        this.terrain_size.x = this.zone.major_radius * 2;
-        this.terrain_size.y = this.zone.minor_radius * 2;
+        this.terrain_size.x = this.zone.template.major_radius * 2;
+        this.terrain_size.y = this.zone.template.minor_radius * 2;
 
         this.cell_count.x = this.terrain_pixel_data.length - 1;
         this.cell_count.y = this.terrain_pixel_data[0].length - 1;
@@ -62,11 +62,11 @@ public class Terrain {
         // the blending area between child and parent terrains when
         // they are stitched together.
 
-        Vector2f major_blend = new Vector2f(this.zone.max_blend / this.zone.major_radius,
-                this.zone.min_blend / this.zone.major_radius);
+        Vector2f major_blend = new Vector2f(this.zone.template.max_blend / this.zone.template.major_radius,
+                this.zone.template.min_blend / this.zone.template.major_radius);
 
-        Vector2f minor_blend = new Vector2f(this.zone.max_blend / this.zone.minor_radius,
-                this.zone.min_blend / this.zone.minor_radius);
+        Vector2f minor_blend = new Vector2f(this.zone.template.max_blend / this.zone.template.minor_radius,
+                this.zone.template.min_blend / this.zone.template.minor_radius);
 
         if (major_blend.y > 0.4f)
             blend_ratio.x = major_blend.y;
@@ -80,7 +80,7 @@ public class Terrain {
 
         // Scale coefficient for this terrain
 
-        this.terrain_scale = this.zone.terrain_max_y / 255f;
+        this.terrain_scale = this.zone.template.terrain_max_y / 255f;
     }
 
     public static Zone getNextZoneWithTerrain(Zone zone) {
@@ -205,8 +205,8 @@ public class Terrain {
 
         // Normalize terrain offset
 
-        Vector2f normalizedOffset = new Vector2f(Math.abs(zone_offset.x) / this.zone.major_radius,
-                Math.abs(zone_offset.y) / this.zone.minor_radius);
+        Vector2f normalizedOffset = new Vector2f(Math.abs(zone_offset.x) / this.zone.template.major_radius,
+                Math.abs(zone_offset.y) / this.zone.template.minor_radius);
 
         float blendCoefficient;
 
diff --git a/src/engine/db/handlers/dbZoneHandler.java b/src/engine/db/handlers/dbZoneHandler.java
index 3300cd76..497c8917 100644
--- a/src/engine/db/handlers/dbZoneHandler.java
+++ b/src/engine/db/handlers/dbZoneHandler.java
@@ -80,6 +80,8 @@ public class dbZoneHandler extends dbHandlerBase {
                 ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
             }
 
+            // Add player city
+
         } catch (SQLException e) {
             Logger.error(e);
         }
diff --git a/src/engine/devcmd/cmds/GetHeightCmd.java b/src/engine/devcmd/cmds/GetHeightCmd.java
index 01f43e6a..4c48abf8 100644
--- a/src/engine/devcmd/cmds/GetHeightCmd.java
+++ b/src/engine/devcmd/cmds/GetHeightCmd.java
@@ -37,8 +37,8 @@ public class GetHeightCmd extends AbstractDevCmd {
 
         Vector2f childZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), heightmapZone);
         Vector2f childZoneOffset = ZoneManager.worldToZoneOffset(playerCharacter.getLoc(), heightmapZone);
-        Vector2f normalizedOffset = new Vector2f(Math.abs(childZoneOffset.x) / heightmapZone.major_radius,
-                Math.abs(childZoneOffset.y) / heightmapZone.minor_radius);
+        Vector2f normalizedOffset = new Vector2f(Math.abs(childZoneOffset.x) / heightmapZone.template.major_radius,
+                Math.abs(childZoneOffset.y) / heightmapZone.template.minor_radius);
         Vector2f parentZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), parentZone);
 
         float childHeight = heightmapZone.terrain.getInterpolatedTerrainHeight(childZoneLoc);
diff --git a/src/engine/devcmd/cmds/ZoneInfoCmd.java b/src/engine/devcmd/cmds/ZoneInfoCmd.java
index 46650c2a..dfd476df 100644
--- a/src/engine/devcmd/cmds/ZoneInfoCmd.java
+++ b/src/engine/devcmd/cmds/ZoneInfoCmd.java
@@ -91,7 +91,7 @@ public class ZoneInfoCmd extends AbstractDevCmd {
         output += newline;
 
         if (zone.terrain != null) {
-            output += "Terrain image: " + zone.terrain_image;
+            output += "Terrain image: " + zone.template.terrain_image;
             output += newline;
         }
 
@@ -99,7 +99,7 @@ public class ZoneInfoCmd extends AbstractDevCmd {
         output += newline;
         //		output += "minLvl = " + zone.getMinLvl() + " | maxLvl = " + zone.getMaxLvl();
         output += newline;
-        output += "Sea Level = " + zone.seaLevel;
+        output += "Sea Level = " + zone.sea_level;
         output += newline;
         output += "World Altitude = " + zone.global_height;
         throwbackInfo(player, output);
diff --git a/src/engine/gameManager/ZoneManager.java b/src/engine/gameManager/ZoneManager.java
index a9b32463..f0bc0a4b 100644
--- a/src/engine/gameManager/ZoneManager.java
+++ b/src/engine/gameManager/ZoneManager.java
@@ -431,6 +431,6 @@ public enum ZoneManager {
         float localAltitude = Terrain.getWorldHeight(currentLoc);
         Zone zone = findSmallestZone(currentLoc);
 
-        return localAltitude < zone.seaLevel;
+        return localAltitude < zone.sea_level;
     }
 }
diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java
index a063df6f..d68c16cd 100644
--- a/src/engine/objects/PlayerCharacter.java
+++ b/src/engine/objects/PlayerCharacter.java
@@ -1507,16 +1507,16 @@ public class PlayerCharacter extends AbstractCharacter {
                 return true;
             Zone zone = ZoneManager.findSmallestZone(breather.getLoc());
 
-            if (zone.seaLevel != 0) {
+            if (zone.sea_level != 0) {
 
                 float localAltitude = breather.getLoc().y;
 
 
-                if (localAltitude + breather.characterHeight < zone.seaLevel - 2)
+                if (localAltitude + breather.characterHeight < zone.sea_level - 2)
                     return false;
 
                 if (breather.isMoving()) {
-                    if (localAltitude + breather.characterHeight < zone.seaLevel)
+                    if (localAltitude + breather.characterHeight < zone.sea_level)
                         return false;
                 }
             } else {
@@ -1547,12 +1547,12 @@ public class PlayerCharacter extends AbstractCharacter {
 
             Zone zone = ZoneManager.findSmallestZone(enterer.getLoc());
 
-            if (zone.seaLevel != 0) {
+            if (zone.sea_level != 0) {
 
                 float localAltitude = enterer.getLoc().y + enterer.characterHeight;
 
 
-                if (localAltitude < zone.seaLevel)
+                if (localAltitude < zone.sea_level)
                     return true;
             } else {
                 if (enterer.getLoc().y + enterer.characterHeight < 0)
@@ -1579,12 +1579,12 @@ public class PlayerCharacter extends AbstractCharacter {
                 leaveWater = 1f;
 
 
-            if (zone.seaLevel != 0) {
+            if (zone.sea_level != 0) {
 
                 float localAltitude = leaver.getLoc().y;
 
 
-                if (localAltitude + leaveWater < zone.seaLevel)
+                if (localAltitude + leaveWater < zone.sea_level)
                     return false;
             } else {
                 if (leaver.getLoc().y + leaveWater < 0)
@@ -4739,10 +4739,10 @@ public class PlayerCharacter extends AbstractCharacter {
 
             Zone zone = ZoneManager.findSmallestZone(this.getLoc());
 
-            if (zone.seaLevel != 0) {
+            if (zone.sea_level != 0) {
 
                 float localAltitude = this.getLoc().y + this.centerHeight;
-                if (localAltitude < zone.seaLevel)
+                if (localAltitude < zone.sea_level)
                     return true;
             } else {
                 if (this.getLoc().y + this.centerHeight < 0)
@@ -4764,9 +4764,9 @@ public class PlayerCharacter extends AbstractCharacter {
 
             Zone zone = ZoneManager.findSmallestZone(currentLoc);
 
-            if (zone.seaLevel != 0) {
+            if (zone.sea_level != 0) {
 
-                if (localAltitude < zone.seaLevel)
+                if (localAltitude < zone.sea_level)
                     return true;
             } else {
                 if (localAltitude < 0)
diff --git a/src/engine/objects/Zone.java b/src/engine/objects/Zone.java
index 942b3eef..07488b5a 100644
--- a/src/engine/objects/Zone.java
+++ b/src/engine/objects/Zone.java
@@ -34,6 +34,8 @@ public class Zone extends AbstractWorldObject {
     public final Set<Building> zoneBuildingSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
     public final Set<NPC> zoneNPCSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
     public final Set<Mob> zoneMobSet = Collections.newSetFromMap(new ConcurrentHashMap<>());
+    public ZoneTemplate template;
+
     public final int playerCityUUID;
     public final String zoneName;
     public final float xOffset;
@@ -58,17 +60,7 @@ public class Zone extends AbstractWorldObject {
     public boolean guild_zone;
     public String hash;
     public float global_height = 0;
-    public float seaLevel = 0f;
-    public float sea_level_offset = 0;
-    public float major_radius;
-    public float minor_radius;
-    public float min_blend;
-    public float max_blend;
-    public String sea_level_type;
     public float sea_level;
-    public String terrain_type;
-    public float terrain_max_y;
-    public int terrain_image;
 
     public Terrain terrain = null;
 
@@ -93,26 +85,6 @@ public class Zone extends AbstractWorldObject {
         this.icon3 = rs.getString("icon3");
         this.min_level = rs.getInt("min_level");
         this.max_level = rs.getInt("max_level");
-        this.major_radius = rs.getFloat("major_radius");
-        this.minor_radius = rs.getFloat("minor_radius");
-        this.min_blend = rs.getFloat("min_blend");
-        this.max_blend = rs.getFloat("max_blend");
-        this.sea_level_type = rs.getString("sea_level_type");
-        this.sea_level_offset = rs.getFloat("sea_level");
-        this.terrain_type = rs.getString("terrain_type");
-        this.terrain_max_y = rs.getFloat("terrain_max_y");
-        this.terrain_image = rs.getInt("terrain_image");
-
-        // Configuration for player cities
-
-        if (this.guild_zone) {
-            this.max_blend = 128;
-            this.min_blend = 128;
-            this.terrain_max_y = 5;
-            this.major_radius = (int) Enum.CityBoundsType.ZONE.halfExtents;
-            this.minor_radius = (int) Enum.CityBoundsType.ZONE.halfExtents;
-            this.terrain_type = "PLANAR";
-        }
 
         // If zone doesn't yet hava a hash then write it back to the zone table
 
@@ -177,12 +149,14 @@ public class Zone extends AbstractWorldObject {
     @Override
     public void runAfterLoad() {
 
+        this.template = ZoneManager._zone_templates.get(this.templateID);
+
         // First zone is always the seafloor
 
         if (ZoneManager.seaFloor == null)
             ZoneManager.seaFloor = this;
 
-        if (this.terrain_type.equals("NONE"))
+        if (this.template.terrain_type.equals("NONE"))
             this.terrain = null;
         else
             this.terrain = new Terrain(this);
@@ -207,7 +181,7 @@ public class Zone extends AbstractWorldObject {
         // Set initial bounds object
 
         this.bounds = Bounds.borrow();
-        this.bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(this.major_radius, this.minor_radius), 0.0f);
+        this.bounds.setBounds(new Vector2f(this.absX, this.absZ), new Vector2f(this.template.major_radius, this.template.minor_radius), 0.0f);
 
     }
 
@@ -225,7 +199,7 @@ public class Zone extends AbstractWorldObject {
             this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE;
             this.global_height = MBServerStatics.SEA_FLOOR_ALTITUDE;
             this.absZ = this.zOffset;
-            this.seaLevel = 0;
+            this.sea_level = 0;
             this.setBounds();
             return;
         }
@@ -253,15 +227,15 @@ public class Zone extends AbstractWorldObject {
             return;
         }
 
-        switch (this.sea_level_type) {
+        switch (this.template.sea_level_type) {
             case "WORLD":
-                this.sea_level = world_sea_level + this.sea_level_offset;
+                this.sea_level = world_sea_level + this.template.sea_level;
                 break;
             case "PARENT":
-                this.sea_level = this.parent.sea_level + this.sea_level_offset;
+                this.sea_level = this.parent.sea_level + this.template.sea_level;
                 break;
             case "SELF":
-                this.sea_level = this.global_height + this.sea_level_offset;
+                this.sea_level = this.global_height + this.template.sea_level;
                 break;
         }
     }
diff --git a/src/engine/objects/ZoneTemplate.java b/src/engine/objects/ZoneTemplate.java
index 017dc121..03ad9619 100644
--- a/src/engine/objects/ZoneTemplate.java
+++ b/src/engine/objects/ZoneTemplate.java
@@ -24,6 +24,7 @@ public class ZoneTemplate {
     public float min_blend;
     public float max_blend;
     public String has_water;
+    public String sea_level_type;
     public float sea_level;
     public String has_terrain;
     public String terrain_type;
@@ -34,6 +35,10 @@ public class ZoneTemplate {
      * ResultSet Constructor
      */
 
+    public ZoneTemplate() {
+
+    }
+
     public ZoneTemplate(ResultSet rs) throws SQLException {
         this.templateID = rs.getInt("template");
         this.zone_type = rs.getString("zone_type");
@@ -44,6 +49,7 @@ public class ZoneTemplate {
         this.min_blend = rs.getFloat("zone_min_blend");
         this.max_blend = rs.getFloat("zone_max_blend");
         this.has_water = rs.getString("zone_has_water");
+        this.sea_level_type = rs.getString("zone_sea_level_type");
         this.sea_level = rs.getFloat("zone_sea_level");
         this.has_terrain = rs.getString("zone_has_terrain_gen");
         this.terrain_type = rs.getString("terrain_type");