diff --git a/src/level.cpp b/src/level.cpp
index 5f9d8bc52d3ece2bf28276445673386925870b61..59f239f04dcfb7bc253f731b2fdb1818ead98e63 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -2,6 +2,9 @@
 #include "building.hpp"
 #include "effect.hpp"
 #include "engine.hpp"
+#include "highfive/H5File.hpp"
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
 #include "spritesheet.hpp"
 #include "ui/contextmenu.hpp"
 #include "ui/pausemenu.hpp"
@@ -44,7 +47,51 @@ Level::Level(
     }
 };
 
-const int RENDERING_SCALE = 3;
+  Level Level::loadLevel(std::string path)
+{
+  HighFive::File file(path, HighFive::File::ReadOnly);
+
+  // read level metadata
+  std::string level_metadata;
+  file.getDataSet("metadata").read(level_metadata);
+
+  // read tilesarray
+  std::vector<uint8_t> level_tilesarray;
+  file.getDataSet("tilesarray").read(level_tilesarray);
+
+  // extract metadata from xml
+  std::istringstream xmlStream(level_metadata);
+  boost::property_tree::ptree pt;
+  boost::property_tree::read_xml(xmlStream, pt);
+  int width = pt.get<int>("level.width");
+  int height = pt.get<int>("level.height");
+  std::string name = pt.get<std::string>("level.name");
+
+  // create tiles and buildings vector from tiles array
+  std::vector<Tile> tiles;
+  std::vector<Building> buildings;
+  tiles.reserve(width*height);
+  for (int i = 0; i < level_tilesarray.size(); i++) 
+  {
+    int x = i % width;
+    int y = i / width;
+    if (level_tilesarray[i] >= 50) {
+      tiles.push_back(Tile(TileId(TileId::PLAIN), x, y));
+      BuildingId building_id = static_cast<BuildingId>((level_tilesarray[i] - 50) % 5);
+      BuildingFaction faction_id = static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5);
+      buildings.push_back(Building(x, y, building_id, faction_id));
+    }
+    else {
+      TileId tile_id = static_cast<TileId>(level_tilesarray[i]);
+      tiles.push_back(Tile(tile_id, x, y));
+    }
+  }
+
+  return Level(name, width, height, tiles, buildings, {}, {});
+};
+
+void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
+  const int RENDERING_SCALE = 3;
 
 bool Level::click_check_left(int tileX, int tileY)
 {
@@ -340,4 +387,4 @@ Effect Level::remove_effect(int id)
     return value;
 }
 
-} // namespace advanced_wars
\ No newline at end of file
+} // namespace advanced_wars
diff --git a/src/level.hpp b/src/level.hpp
index f3b53f9db4cd65e93d085aafa20828cbcc462fc7..efdc855ac93d8ff570b1a4d382ef2395afe48388 100644
--- a/src/level.hpp
+++ b/src/level.hpp
@@ -25,6 +25,8 @@ class Level : public Scene
             std::string name, int width, int height, std::vector<Tile> tiles,
             std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect>);
 
+        static Level loadLevel(std::string path);
+
         void render(Engine* engine);
 
         void handleEvent(Engine* engine, SDL_Event& event);