diff --git a/src/main/java/com/syncleus/aethermud/Main.java b/src/main/java/com/syncleus/aethermud/Main.java
index 09793c2887294916b48e7deb87d206016a54c636..060c17ebc5201f420e02f4154ecfd62de893e7a3 100644
--- a/src/main/java/com/syncleus/aethermud/Main.java
+++ b/src/main/java/com/syncleus/aethermud/Main.java
@@ -30,23 +30,15 @@ import com.syncleus.aethermud.player.PlayerManagementManager;
 import com.syncleus.aethermud.player.PlayerManager;
 import com.syncleus.aethermud.server.communication.ChannelUtils;
 import com.syncleus.aethermud.server.telnet.AetherMudServer;
-import com.syncleus.aethermud.storage.WorldStorage;
 import com.syncleus.aethermud.storage.graphdb.*;
-import com.syncleus.aethermud.storage.graphdb.model.*;
 import com.syncleus.aethermud.world.MapsManager;
 import com.syncleus.aethermud.world.RoomManager;
 import com.google.common.io.Files;
-import com.syncleus.ferma.DelegatingFramedGraph;
-import com.syncleus.ferma.WrappedFramedGraph;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.configuration.*;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.log4j.Logger;
-import org.apache.tinkerpop.gremlin.structure.Graph;
-import org.apache.tinkerpop.gremlin.structure.io.IoCore;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
 import java.io.File;
-import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -103,8 +95,10 @@ public class Main {
         GameManager gameManager = new GameManager(graphStorageFactory, aetherMudConfiguration, roomManager, playerManager, entityManager, mapsManager, channelUtils, HttpClients.createDefault());
 
         startUpMessage("Reading world from disk.");
-        WorldStorage worldExporter = new WorldStorage(roomManager, mapsManager, gameManager.getFloorManager(), entityManager, gameManager);
-        worldExporter.readWorldFromDisk();
+        try( GraphStorageFactory.AetherMudTx tx = gameManager.getGraphStorageFactory().beginTransaction() ) {
+            tx.getStorage().loadWorld(mapsManager, entityManager, gameManager);
+            tx.success();
+        }
 
         startUpMessage("Creating and registering Player Management MBeans.");
         PlayerManagementManager playerManagementManager = new PlayerManagementManager(gameManager);
diff --git a/src/main/java/com/syncleus/aethermud/command/commands/Command.java b/src/main/java/com/syncleus/aethermud/command/commands/Command.java
index cd3c03203831fbbb08aca3116ab7c6640116a8bb..2b9b487052316de7771441866c9d99e1f2166321 100644
--- a/src/main/java/com/syncleus/aethermud/command/commands/Command.java
+++ b/src/main/java/com/syncleus/aethermud/command/commands/Command.java
@@ -24,7 +24,6 @@ import com.syncleus.aethermud.player.PlayerManager;
 import com.syncleus.aethermud.player.PlayerRole;
 import com.syncleus.aethermud.server.model.AetherMudSession;
 import com.syncleus.aethermud.server.communication.ChannelCommunicationUtils;
-import com.syncleus.aethermud.storage.WorldStorage;
 import com.syncleus.aethermud.world.FloorManager;
 import com.syncleus.aethermud.world.MapMatrix;
 import com.syncleus.aethermud.world.MapsManager;
@@ -63,7 +62,6 @@ public abstract class Command extends SimpleChannelUpstreamHandler {
     public Optional<MapMatrix> mapMatrix = Optional.empty();
     public Optional<Coords> currentRoomCoords = Optional.empty();
     public List<String> originalMessageParts;
-    public WorldStorage worldExporter;
     public String rootCommand;
 
     protected Command(GameManager gameManager, List<String> validTriggers, String description, String correctUsage) {
@@ -81,7 +79,6 @@ public abstract class Command extends SimpleChannelUpstreamHandler {
         this.entityManager = gameManager.getEntityManager();
         this.playerManager = gameManager.getPlayerManager();
         this.channelUtils = gameManager.getChannelUtils();
-        this.worldExporter = new WorldStorage(roomManager, mapsManager, floorManager, entityManager, gameManager);
         this.lootManager = gameManager.getLootManager();
         this.roles = roles;
     }
diff --git a/src/main/java/com/syncleus/aethermud/command/commands/admin/BuildCommand.java b/src/main/java/com/syncleus/aethermud/command/commands/admin/BuildCommand.java
index e103b2fe6871c94d747c4b42eebca8f64d587bdf..98b48ba453e42c8d127759279c93d71d25a1294e 100644
--- a/src/main/java/com/syncleus/aethermud/command/commands/admin/BuildCommand.java
+++ b/src/main/java/com/syncleus/aethermud/command/commands/admin/BuildCommand.java
@@ -19,7 +19,7 @@ import com.syncleus.aethermud.command.commands.Command;
 import com.syncleus.aethermud.core.GameManager;
 import com.syncleus.aethermud.player.PlayerMovement;
 import com.syncleus.aethermud.player.PlayerRole;
-import com.syncleus.aethermud.storage.WorldStorage;
+import com.syncleus.aethermud.storage.AetherMudStorage;
 import com.syncleus.aethermud.world.MapMatrix;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -225,7 +225,7 @@ 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(WorldStorage.buildRoomModelsFromRooms()).collect(Collectors.toSet());
+        Set<RoomModel> roomModels = Sets.newHashSet(newRoom).stream().map(AetherMudStorage.buildRoomModelsFromRooms()).collect(Collectors.toSet());
         newFloorModel.setRoomModels(roomModels);
         floorManager.addFloor(newFloorModel.getId(), newFloorModel.getName());
         MapMatrix matrixFromCsv = MapMatrix.createMatrixFromCsv(newFloorModel.getRawMatrixCsv());
diff --git a/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadWorldCommand.java b/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadWorldCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..148eddb8d5d0dc9cd1a1c90e9984fe0266a6607c
--- /dev/null
+++ b/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadWorldCommand.java
@@ -0,0 +1,126 @@
+/**
+ * Copyright 2017 - 2018 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.syncleus.aethermud.command.commands.admin;
+
+import com.syncleus.aethermud.command.commands.Command;
+import com.syncleus.aethermud.core.GameManager;
+import com.syncleus.aethermud.npc.Npc;
+import com.syncleus.aethermud.player.PlayerRole;
+import com.syncleus.aethermud.spawner.SpawnRule;
+import com.syncleus.aethermud.storage.AetherMudStorage;
+import com.syncleus.aethermud.storage.graphdb.GraphStorageFactory;
+import com.syncleus.aethermud.storage.graphdb.model.NpcData;
+import com.google.common.collect.Sets;
+import com.syncleus.aethermud.world.model.WorldModel;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.util.EntityUtils;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+
+public class LoadWorldCommand extends Command {
+
+    final static List<String> validTriggers = Arrays.asList("loadworld");
+    final static String description = "Load a World using JSON over http";
+    final static String correctUsage = "loadworld <http url with json for world>";
+    final static Set<PlayerRole> roles = Sets.newHashSet(PlayerRole.ADMIN);
+
+    public LoadWorldCommand(GameManager gameManager) {
+        super(gameManager, validTriggers, description, correctUsage, roles);
+    }
+
+    @Override
+    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+        execCommand(ctx, e, () -> {
+
+            if (originalMessageParts.size() <= 1) {
+                write("Please specify a http url." + "\r\n");
+                return;
+            }
+
+            originalMessageParts.remove(0);
+
+
+            String worldJsonHttpUrl = originalMessageParts.get(0);
+            if (!isValidURL(worldJsonHttpUrl)) {
+                write("Invalid HTTP address." + "\r\n");
+                return;
+            }
+
+            HttpGet httpGet = new HttpGet(worldJsonHttpUrl);
+
+            HttpClient httpclient = gameManager.getHttpclient();
+
+            HttpResponse httpResponse = httpclient.execute(httpGet);
+
+            HttpEntity entity = httpResponse.getEntity();
+
+            if (entity == null) {
+                write("Error retrieving JSON url." + "\r\n");
+                return;
+            }
+
+            String worldJson = EntityUtils.toString(entity);
+
+            WorldModel world = null;
+            try {
+                world = gameManager.getGson().fromJson(worldJson, WorldModel.class);
+            } catch (Exception ex) {
+                write("Retrieved JSON file is malformed. " + ex.getLocalizedMessage() + "\r\n");
+                return;
+            }
+            httpGet.reset();
+
+            try( GraphStorageFactory.AetherMudTx tx = this.gameManager.getGraphStorageFactory().beginTransaction() ) {
+                AetherMudStorage storage = tx.getStorage();
+                storage.loadWorld( roomManager, mapsManager, entityManager, gameManager, world);
+                tx.success();
+            }
+
+        });
+    }
+
+    public boolean isValidURL(String url) {
+        URL u = null;
+        try {
+            u = new URL(url);
+        } catch (MalformedURLException e) {
+            return false;
+        }
+        try {
+            u.toURI();
+        } catch (URISyntaxException e) {
+            return false;
+        }
+        return true;
+    }
+
+}
+
+
+
diff --git a/src/main/java/com/syncleus/aethermud/command/commands/admin/SaveWorldCommand.java b/src/main/java/com/syncleus/aethermud/command/commands/admin/SaveWorldCommand.java
index aa5aac732acd5c63601be569bb9cf30967b454ed..15c6b42c40aa7fb26139c4ec401b0b2b93daa37f 100644
--- a/src/main/java/com/syncleus/aethermud/command/commands/admin/SaveWorldCommand.java
+++ b/src/main/java/com/syncleus/aethermud/command/commands/admin/SaveWorldCommand.java
@@ -19,6 +19,7 @@ import com.syncleus.aethermud.command.commands.Command;
 import com.syncleus.aethermud.core.GameManager;
 import com.syncleus.aethermud.player.PlayerRole;
 import com.google.common.collect.Sets;
+import com.syncleus.aethermud.storage.graphdb.GraphStorageFactory;
 import org.jboss.netty.channel.ChannelHandlerContext;
 import org.jboss.netty.channel.MessageEvent;
 
@@ -40,7 +41,10 @@ public class SaveWorldCommand extends Command {
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
         execCommandThreadSafe(ctx, e, SaveWorldCommand.class, () -> {
-            worldExporter.saveWorld();
+            try( GraphStorageFactory.AetherMudTx tx = this.gameManager.getGraphStorageFactory().beginTransaction() ) {
+                tx.getStorage().saveWorld(roomManager, mapsManager, floorManager);
+                tx.success();
+            }
             write("World saved.");
         });
     }
diff --git a/src/main/java/com/syncleus/aethermud/configuration/ConfigureCommands.java b/src/main/java/com/syncleus/aethermud/configuration/ConfigureCommands.java
index f6810727a0ec28107d8d2c9e6eb2c47bdef5e55b..bc838b20ac6ef9bf31921216d2cc3a29706caf64 100644
--- a/src/main/java/com/syncleus/aethermud/configuration/ConfigureCommands.java
+++ b/src/main/java/com/syncleus/aethermud/configuration/ConfigureCommands.java
@@ -120,6 +120,7 @@ public class ConfigureCommands {
         commandRegistry.addCommand(new LoadNpcCommand(gameManager));
         commandRegistry.addCommand(new LoadItemCommand(gameManager));
         commandRegistry.addCommand(new LoadMerchantCommand(gameManager));
+        commandRegistry.addCommand(new LoadWorldCommand(gameManager));
         commandRegistry.addCommand(new RestartCommand(gameManager));
         commandRegistry.addCommand(new GiveHealthCommand(gameManager));
         commandRegistry.addCommand(new GraphStatusCommand(gameManager));
diff --git a/src/main/java/com/syncleus/aethermud/storage/AetherMudStorage.java b/src/main/java/com/syncleus/aethermud/storage/AetherMudStorage.java
index 8cb5840f5f71af71e43c6ceb7df1f0b3bb0a14ca..477b5214b7ea73a6f73f15f20de160a4ae308d7b 100644
--- a/src/main/java/com/syncleus/aethermud/storage/AetherMudStorage.java
+++ b/src/main/java/com/syncleus/aethermud/storage/AetherMudStorage.java
@@ -17,15 +17,21 @@ package com.syncleus.aethermud.storage;
 
 
 import com.syncleus.aethermud.core.GameManager;
+import com.syncleus.aethermud.entity.EntityManager;
 import com.syncleus.aethermud.items.Item;
 import com.syncleus.aethermud.items.ItemInstance;
 import com.syncleus.aethermud.merchant.Merchant;
 import com.syncleus.aethermud.npc.NpcSpawn;
 import com.syncleus.aethermud.storage.graphdb.model.*;
+import com.syncleus.aethermud.world.FloorManager;
+import com.syncleus.aethermud.world.MapsManager;
+import com.syncleus.aethermud.world.RoomManager;
+import com.syncleus.aethermud.world.model.*;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.function.Function;
 
 public interface AetherMudStorage {
 
@@ -66,4 +72,31 @@ public interface AetherMudStorage {
     Optional<MerchantData> getMerchantData(String internalName);
 
     MerchantData newMerchantData();
+    
+    void saveWorld(RoomManager roomManager, MapsManager mapsManager, FloorManager floorManager);
+    
+    void loadWorld(MapsManager mapsManager, EntityManager entityManager, GameManager gameManager);
+    
+    void loadWorld(RoomManager roomManager, MapsManager mapsManager, EntityManager entityManager, GameManager gameManager, WorldModel worldModel);
+
+    static Function<Room, RoomModel> buildRoomModelsFromRooms() {
+        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();
+        };
+    }
 }
diff --git a/src/main/java/com/syncleus/aethermud/storage/WorldStorage.java b/src/main/java/com/syncleus/aethermud/storage/WorldStorage.java
deleted file mode 100644
index ede7cc010d79cba9205f933a3d1094f6c2d25007..0000000000000000000000000000000000000000
--- a/src/main/java/com/syncleus/aethermud/storage/WorldStorage.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * Copyright 2017 - 2018 Syncleus, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.syncleus.aethermud.storage;
-
-import com.syncleus.aethermud.core.GameManager;
-import com.syncleus.aethermud.core.SentryManager;
-import com.syncleus.aethermud.entity.EntityManager;
-import com.syncleus.aethermud.world.FloorManager;
-import com.syncleus.aethermud.world.MapMatrix;
-import com.syncleus.aethermud.world.MapsManager;
-import com.syncleus.aethermud.world.RoomManager;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-import com.google.gson.GsonBuilder;
-import com.syncleus.aethermud.world.model.*;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.util.*;
-import java.util.function.Function;
-
-public class WorldStorage {
-
-    private final static String WORLD_DIR = "world/";
-
-    private final RoomManager roomManager;
-    private final MapsManager mapsManager;
-    private final FloorManager floorManager;
-    private final EntityManager entityManager;
-    private final GameManager gameManager;
-
-    public WorldStorage(RoomManager roomManager, MapsManager mapsManager, FloorManager floorManager, EntityManager entityManager, GameManager gameManager) {
-        this.roomManager = roomManager;
-        this.mapsManager = mapsManager;
-        this.floorManager = floorManager;
-        this.entityManager = entityManager;
-        this.gameManager = gameManager;
-    }
-
-    public void saveWorld() {
-        WorldModel worldModel = new WorldModel();
-        Set<FloorModel> floors = Sets.newHashSet();
-        Set<Integer> floorIds = floorManager.getFloorIds();
-        for (Integer floorId : floorIds) {
-            floors.add(generateFloorModel(floorId, mapsManager.getFloorMatrixMaps().get(floorId)));
-        }
-        worldModel.setFloorModelList(floors);
-
-        String worldJson = new GsonBuilder().setPrettyPrinting().create().toJson(worldModel, WorldModel.class);
-        try {
-            Files.write(worldJson.getBytes(), new File(WORLD_DIR + "world.json"));
-        } catch (IOException e) {
-            SentryManager.logSentry(this.getClass(), e, "Save world problem!");
-            e.printStackTrace();
-        }
-    }
-
-    private FloorModel generateFloorModel(Integer floorId, MapMatrix mapMatrix) {
-        Set<Room> rooms = roomManager.getRoomsByFloorId(floorId);
-        FloorModel floorModel = new FloorModel();
-        floorModel.setId(floorId);
-        floorModel.setRawMatrixCsv(mapMatrix.getCsv());
-        floorModel.setRoomModels((new HashSet<RoomModel>()));
-        floorModel.setName(floorManager.getName(floorId));
-        rooms.stream()
-                .map(buildRoomModelsFromRooms())
-                .forEach(roomModel -> floorModel.getRoomModels()
-                        .add(roomModel));
-        return floorModel;
-    }
-
-    public static Function<Room, RoomModel> buildRoomModelsFromRooms() {
-        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 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) {
-                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) {
-                for (Map.Entry<String, String> next : notables.entrySet()) {
-                    basicRoomBuilder.addNotable(next.getKey(), next.getValue());
-                }
-            }
-            configureExits(basicRoomBuilder, mapMatrix, roomModel.getRoomId());
-            return basicRoomBuilder.createBasicRoom();
-        };
-    }
-
-    private void configureExits(BasicRoomBuilder basicRoomBuilder, MapMatrix mapMatrix, int roomId) {
-        Integer north = mapMatrix.getNorthernExit(roomId);
-        if (north > 0) {
-            basicRoomBuilder.setNorthId(Optional.of(north));
-        }
-        Integer east = mapMatrix.getEasternExit(roomId);
-        if (east > 0) {
-            basicRoomBuilder.setEastId(Optional.of(east));
-        }
-        Integer south = mapMatrix.getSouthernExit(roomId);
-        if (south > 0) {
-            basicRoomBuilder.setSouthId(Optional.of(south));
-        }
-        Integer west = mapMatrix.getWesternExit(roomId);
-        if (west > 0) {
-            basicRoomBuilder.setWestId(Optional.of(west));
-        }
-        if (mapMatrix.getRemotes().containsKey(roomId)) {
-            for (RemoteExit exit : mapMatrix.getRemotes().get(roomId)) {
-                if (exit.getDirection().equals(RemoteExit.Direction.UP)) {
-                    basicRoomBuilder.setUpId(Optional.of(exit.getRoomId()));
-                } else if (exit.getDirection().equals(RemoteExit.Direction.DOWN)) {
-                    basicRoomBuilder.setDownId(Optional.of(exit.getRoomId()));
-                }
-            }
-        }
-    }
-
-    private void buildFloor(FloorModel floorModel) {
-        MapMatrix matrixFromCsv = MapMatrix.createMatrixFromCsv(floorModel.getRawMatrixCsv());
-        Set<Room> rooms = Sets.newHashSet();
-        if (floorModel.getRoomModels() == null || floorModel.getRoomModels().size() == 0) {
-            Iterator<List<Integer>> rows = matrixFromCsv.getRows();
-            while (rows.hasNext()) {
-                List<Integer> row = rows.next();
-                for (Integer roomId : row) {
-                    if (roomId.equals(0)) {
-                        continue;
-                    }
-                    BasicRoomBuilder basicRoomBuilder = new BasicRoomBuilder(gameManager);
-                    basicRoomBuilder.setFloorId(floorModel.getId());
-                    basicRoomBuilder.setRoomId(roomId);
-                    basicRoomBuilder.setRoomTitle("This is a blank title.");
-                    basicRoomBuilder.setRoomDescription("This is a blank Description.\nWords should go here, ideally.");
-                    configureExits(basicRoomBuilder, matrixFromCsv, roomId);
-                    rooms.add(basicRoomBuilder.createBasicRoom());
-                }
-            }
-            for (Room r : rooms) {
-                entityManager.addEntity(r);
-            }
-            floorManager.addFloor(floorModel.getId(), floorModel.getName());
-            mapsManager.addFloorMatrix(floorModel.getId(), matrixFromCsv);
-            return;
-        }
-        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/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java b/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java
index f515c05be5d1b26e12778bde7650992901580190..af7066eb9f508d588c8c69ea4a4edfcb87aa0263 100644
--- a/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java
+++ b/src/main/java/com/syncleus/aethermud/storage/graphdb/GraphDbAetherMudStorage.java
@@ -17,7 +17,10 @@ package com.syncleus.aethermud.storage.graphdb;
 
 import com.google.common.collect.Interner;
 import com.google.common.collect.Interners;
+import com.google.common.collect.Sets;
+import com.google.gson.GsonBuilder;
 import com.syncleus.aethermud.core.GameManager;
+import com.syncleus.aethermud.entity.EntityManager;
 import com.syncleus.aethermud.items.Item;
 import com.syncleus.aethermud.items.ItemInstance;
 import com.syncleus.aethermud.merchant.Merchant;
@@ -26,12 +29,18 @@ import com.syncleus.aethermud.npc.NpcSpawn;
 import com.syncleus.aethermud.storage.AetherMudStorage;
 import com.syncleus.aethermud.storage.GraphInfo;
 import com.syncleus.aethermud.storage.graphdb.model.*;
+import com.syncleus.aethermud.world.FloorManager;
+import com.syncleus.aethermud.world.MapMatrix;
+import com.syncleus.aethermud.world.MapsManager;
+import com.syncleus.aethermud.world.RoomManager;
+import com.syncleus.aethermud.world.model.*;
 import com.syncleus.ferma.VertexFrame;
 import com.syncleus.ferma.WrappedFramedGraph;
 import org.apache.log4j.Logger;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 public class GraphDbAetherMudStorage implements AetherMudStorage {
@@ -194,4 +203,163 @@ public class GraphDbAetherMudStorage implements AetherMudStorage {
     public MerchantData newMerchantData() {
         return framedGraph.addFramedVertex(MerchantData.class);
     }
+    
+    @Override
+    public void loadWorld(RoomManager roomManager, MapsManager mapsManager, EntityManager entityManager, GameManager gameManager, WorldModel worldModel) {
+        for( FloorModel floorModel : worldModel.getFloorModelList())
+            this.buildFloor(mapsManager, entityManager, gameManager, floorModel);
+        this.saveWorld(roomManager, mapsManager, gameManager.getFloorManager());
+    }
+    
+    @Override
+    public void loadWorld( MapsManager mapsManager, EntityManager entityManager, GameManager gameManager) {
+        WorldModelData data = framedGraph.traverse((g) -> framedGraph.getTypeResolver().hasType(g.V(), WorldModelData.class)).nextOrDefault(WorldModelData.class,null);
+        if( data != null) {
+            WorldModel worldModel = WorldModelData.copyWorldModel(data);
+            for( FloorModel floorModel : worldModel.getFloorModelList())
+                this.buildFloor(mapsManager, entityManager, gameManager, floorModel);
+        } else {
+            this.buildEmptyWorld(mapsManager, entityManager, gameManager);
+        }
+    }
+    
+    @Override
+    public void saveWorld(RoomManager roomManager, MapsManager mapsManager, FloorManager floorManager) {
+        WorldModel worldModel = new WorldModel();
+        Set<FloorModel> floors = Sets.newHashSet();
+        Set<Integer> floorIds = floorManager.getFloorIds();
+        for (Integer floorId : floorIds) {
+            floors.add(generateFloorModel(roomManager, floorManager, floorId, mapsManager.getFloorMatrixMaps().get(floorId)));
+        }
+        worldModel.setFloorModelList(floors);
+        
+        WorldModelData data = framedGraph.traverse((g) -> framedGraph.getTypeResolver().hasType(g.V(), WorldModelData.class)).nextOrDefault(WorldModelData.class,null);
+        if( data == null )
+            data = framedGraph.addFramedVertex(WorldModelData.class);
+        WorldModelData.copyWorldModel(data, worldModel);
+    }
+    
+    private FloorModel generateFloorModel(RoomManager roomManager, FloorManager floorManager, Integer floorId, MapMatrix mapMatrix) {
+        Set<Room> rooms = roomManager.getRoomsByFloorId(floorId);
+        FloorModel floorModel = new FloorModel();
+        floorModel.setId(floorId);
+        floorModel.setRawMatrixCsv(mapMatrix.getCsv());
+        floorModel.setRoomModels((new HashSet<RoomModel>()));
+        floorModel.setName(floorManager.getName(floorId));
+        rooms.stream()
+                .map(AetherMudStorage.buildRoomModelsFromRooms())
+                .forEach(roomModel -> floorModel.getRoomModels()
+                        .add(roomModel));
+        return floorModel;
+    }
+
+    public Function<RoomModel, BasicRoom> getBasicRoom(GameManager gameManager, final MapMatrix mapMatrix) {
+        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) {
+                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) {
+                for (Map.Entry<String, String> next : notables.entrySet()) {
+                    basicRoomBuilder.addNotable(next.getKey(), next.getValue());
+                }
+            }
+            configureExits(basicRoomBuilder, mapMatrix, roomModel.getRoomId());
+            return basicRoomBuilder.createBasicRoom();
+        };
+    }
+
+    private void configureExits(BasicRoomBuilder basicRoomBuilder, MapMatrix mapMatrix, int roomId) {
+        Integer north = mapMatrix.getNorthernExit(roomId);
+        if (north > 0) {
+            basicRoomBuilder.setNorthId(Optional.of(north));
+        }
+        Integer east = mapMatrix.getEasternExit(roomId);
+        if (east > 0) {
+            basicRoomBuilder.setEastId(Optional.of(east));
+        }
+        Integer south = mapMatrix.getSouthernExit(roomId);
+        if (south > 0) {
+            basicRoomBuilder.setSouthId(Optional.of(south));
+        }
+        Integer west = mapMatrix.getWesternExit(roomId);
+        if (west > 0) {
+            basicRoomBuilder.setWestId(Optional.of(west));
+        }
+        if (mapMatrix.getRemotes().containsKey(roomId)) {
+            for (RemoteExit exit : mapMatrix.getRemotes().get(roomId)) {
+                if (exit.getDirection().equals(RemoteExit.Direction.UP)) {
+                    basicRoomBuilder.setUpId(Optional.of(exit.getRoomId()));
+                } else if (exit.getDirection().equals(RemoteExit.Direction.DOWN)) {
+                    basicRoomBuilder.setDownId(Optional.of(exit.getRoomId()));
+                }
+            }
+        }
+    }
+
+    private void buildFloor(MapsManager mapsManager, EntityManager entityManager, GameManager gameManager, FloorModel floorModel) {
+        MapMatrix matrixFromCsv = MapMatrix.createMatrixFromCsv(floorModel.getRawMatrixCsv());
+        Set<Room> rooms = Sets.newHashSet();
+        if (floorModel.getRoomModels() == null || floorModel.getRoomModels().size() == 0) {
+            Iterator<List<Integer>> rows = matrixFromCsv.getRows();
+            while (rows.hasNext()) {
+                List<Integer> row = rows.next();
+                for (Integer roomId : row) {
+                    if (roomId.equals(0)) {
+                        continue;
+                    }
+                    BasicRoomBuilder basicRoomBuilder = new BasicRoomBuilder(gameManager);
+                    basicRoomBuilder.setFloorId(floorModel.getId());
+                    basicRoomBuilder.setRoomId(roomId);
+                    basicRoomBuilder.setRoomTitle("This is a blank title.");
+                    basicRoomBuilder.setRoomDescription("This is a blank Description.\nWords should go here, ideally.");
+                    configureExits(basicRoomBuilder, matrixFromCsv, roomId);
+                    rooms.add(basicRoomBuilder.createBasicRoom());
+                }
+            }
+            for (Room r : rooms) {
+                entityManager.addEntity(r);
+            }
+            gameManager.getFloorManager().addFloor(floorModel.getId(), floorModel.getName());
+            mapsManager.addFloorMatrix(floorModel.getId(), matrixFromCsv);
+            return;
+        }
+        floorModel.getRoomModels().stream().map(getBasicRoom(gameManager, matrixFromCsv)).forEach(entityManager::addEntity);
+        gameManager.getFloorManager().addFloor(floorModel.getId(), floorModel.getName());
+        mapsManager.addFloorMatrix(floorModel.getId(), matrixFromCsv);
+    }
+    
+    private void buildEmptyWorld(MapsManager mapsManager, EntityManager entityManager, GameManager gameManager) {
+        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(mapsManager, entityManager, gameManager, next);
+        }
+    }
 }
diff --git a/src/test/java/com/syncleus/aethermud/player/combatsimuation/NpcTestHarness.java b/src/test/java/com/syncleus/aethermud/player/combatsimuation/NpcTestHarness.java
index 077739b09eb7fba4616c21f78a809236cbd589de..44ceb5a7103ff5143e4ff8a78c5b1fbfd1f73d03 100644
--- a/src/test/java/com/syncleus/aethermud/player/combatsimuation/NpcTestHarness.java
+++ b/src/test/java/com/syncleus/aethermud/player/combatsimuation/NpcTestHarness.java
@@ -30,7 +30,6 @@ import com.syncleus.aethermud.server.communication.ChannelCommunicationUtils;
 import com.syncleus.aethermud.stats.DefaultStats;
 import com.syncleus.aethermud.stats.Levels;
 import com.syncleus.aethermud.stats.experience.Experience;
-import com.syncleus.aethermud.storage.WorldStorage;
 import com.syncleus.aethermud.storage.graphdb.GraphStorageFactory;
 import com.syncleus.aethermud.storage.graphdb.model.PlayerData;
 import com.syncleus.aethermud.world.MapsManager;
@@ -345,8 +344,10 @@ public class NpcTestHarness {
         MapsManager mapsManager = new MapsManager(aetherMudConfiguration, roomManager);
         EntityManager entityManager = new EntityManager(storageFactory, roomManager, playerManager);
         GameManager gameManager = new GameManager(storageFactory, aetherMudConfiguration, roomManager, playerManager, entityManager, mapsManager, channelUtils, HttpClients.createDefault());
-        WorldStorage worldExporter = new WorldStorage(roomManager, mapsManager, gameManager.getFloorManager(), entityManager, gameManager);
-        worldExporter.buildTestworld();
+        try( GraphStorageFactory.AetherMudTx tx = gameManager.getGraphStorageFactory().beginTransaction() ) {
+            tx.getStorage().loadWorld(mapsManager, entityManager, gameManager);
+            tx.success();
+        }
         ConfigureCommands.configure(gameManager);
         this.entityManager = entityManager;
         this.gameManager = gameManager;