diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt
index 6c99e28311d3431e664dc0d0c3764c7d16fca7f6..ddda5b2b34a39c4fba15156fea97c5d84d2b8052 100644
--- a/editor/CMakeLists.txt
+++ b/editor/CMakeLists.txt
@@ -12,7 +12,8 @@ set(EDITOR_SOURCES src/main.cpp src/EditorApp.cpp
         src/TileBar.cpp
         src/TileBar.hpp
         src/GridItem.cpp
-        src/GridItem.hpp)
+        src/GridItem.hpp
+        src/HDF5Handler.cpp)
 
 set(CMAKE_AUTOMOC ON)
 
diff --git a/editor/src/CenterGrid.cpp b/editor/src/CenterGrid.cpp
index dc2ca406f703280f5bad0a65725089c20e26cfb1..ede515b25afd4f00f0d5368c46077b5875cd4497 100644
--- a/editor/src/CenterGrid.cpp
+++ b/editor/src/CenterGrid.cpp
@@ -15,19 +15,24 @@ CenterGrid::CenterGrid(QWidget* parent)
     view->setAlignment(Qt::AlignCenter | Qt::AlignCenter);
 
     // Initialize the 2D container
+    m_currentSpriteID = -1;
     const int rows = 64;
     const int cols = 64;
     gridItems.resize(rows);
-    for (int row = 0; row < rows; ++row) 
-    {
+    m_tileIDs.resize(rows);
+    for (int row = 0; row < rows; row++) {
         gridItems[row].resize(cols);
+        m_tileIDs[row].resize(cols);
+        for (int col = 0; col < cols; col++) {
+            m_tileIDs[row][col] = m_currentSpriteID;
+        }
     }
 
     // Create tiles
     const qreal tileSize = 20.0;
-    for (int row = 0; row < rows; ++row) 
+    for (int row = 0; row < rows; row++) 
     {
-        for (int col = 0; col < cols; ++col) 
+        for (int col = 0; col < cols; col++) 
         {
             GridItem* tile = new GridItem(row, col, tileSize);
             tile->setPos(col * tileSize, row * tileSize);
@@ -38,7 +43,7 @@ CenterGrid::CenterGrid(QWidget* parent)
     }
 
     // Set initial grid boundaries
-    scene->setSceneRect(0, 0, 64*tileSize, 64*tileSize);
+    scene->setSceneRect(0, 0, 64 * tileSize, 64 * tileSize);
 
     // Set Layout
     QVBoxLayout* layout = new QVBoxLayout(this);
@@ -59,15 +64,17 @@ void CenterGrid::resizeEvent(QResizeEvent* event)
     view->fitInView(scene->sceneRect(), Qt::KeepAspectRatio);
 }
 
-void CenterGrid::setCurrentSprite(const QPixmap pixmap) 
+void CenterGrid::setCurrentSprite(const QPixmap pixmap, const int id) 
 {
     m_currentSprite = pixmap;
+    m_currentSpriteID = id;
 }
 
 void CenterGrid::onTileClicked(int row, int col) 
 {
     GridItem* tile = getTile(row,col);
     tile->setPixmap(m_currentSprite);
+    m_tileIDs[row][col] = m_currentSpriteID;
 }
 
 GridItem* CenterGrid::getTile(int row, int col) const 
@@ -79,6 +86,11 @@ GridItem* CenterGrid::getTile(int row, int col) const
     return nullptr;
 }
 
+QVector<QVector<int>> CenterGrid::getTileIDs() 
+{
+    return m_tileIDs;
+}
+
 void CenterGrid::drawPreset(int index)
 {
     QList<QGraphicsItem*> items = scene->items();
diff --git a/editor/src/CenterGrid.hpp b/editor/src/CenterGrid.hpp
index d14d51be011abb8e4df585d70fd6e03b2b7bf140..31480850073aa03129196f46227efd969131423c 100644
--- a/editor/src/CenterGrid.hpp
+++ b/editor/src/CenterGrid.hpp
@@ -30,7 +30,7 @@ public:
     * @brief Setter function to update which sprite is currently selected and needs to be places when grid clicked
     * @param message TEMPORARY message that is shown when tile is clicked replace with sprite data
     */
-    void setCurrentSprite(const QPixmap pixmap);
+    void setCurrentSprite(const QPixmap pixmap, const int id);
 
     /**
     * @brief Function for drawing the currently selected sprite on a tile when tile is clicked
@@ -53,6 +53,12 @@ public:
     */
     GridItem* getTile(int row, int col) const;
 
+    /**
+    * @brief getter function for Vector of TileIDs
+    * @return QVector<QVector<int>> of TileIDs
+    */
+    QVector<QVector<int>> getTileIDs();
+
 private:
 
     /**
@@ -76,10 +82,20 @@ private:
     */
     QPixmap m_currentSprite;
 
+    /**
+    * @brief ID of the currently selected sprite
+    */
+    int m_currentSpriteID;
+
     /**
     * @brief 2D Vector holding all GridItems, making them accessible by position on grid
     */
     QVector<QVector<GridItem*>> gridItems;
+
+    /**
+    * @brief 2D Vector holding all GridItems, making them accessible by position on grid
+    */
+    QVector<QVector<int>> m_tileIDs;
 };
 
 } // namespace editor
\ No newline at end of file
diff --git a/editor/src/HDF5Handler.cpp b/editor/src/HDF5Handler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3f9062d7b6c12a598214f1a634b2cea70dc66b6
--- /dev/null
+++ b/editor/src/HDF5Handler.cpp
@@ -0,0 +1,63 @@
+#include "HDF5Handler.hpp"
+
+namespace editor
+{
+
+HDF5Handler::HDF5Handler() : m_Level("./tileset.png", 16)
+{
+}
+
+HDF5Handler::HDF5Handler(const std::filesystem::path path) : m_Level(path)
+{
+}
+
+void HDF5Handler::loadTilesheet(TileBar* tileBar) const
+{
+    const unsigned char* tiledata = m_Level.getSpritesheet().getSpritedata().data();
+    const int width = m_Level.getSpritesheet().getWidth();
+    const int height = m_Level.getSpritesheet().getHeight();
+
+    const QImage image(tiledata, width, height, QImage::Format_RGBA8888);
+    QPixmap pixmap = QPixmap::fromImage(image);
+
+    // TODO: Move this to the Spritesheet class in Liblvl
+    const int32_t maxId = (width / 16) * (height / 16);
+
+    QStringList tileNames;
+    QList<QPixmap> tiles;
+
+    for (int32_t i = 0; i < maxId; i++)
+    {
+        auto [x, y] = m_Level.getSpritesheet().getTilePosition(i);
+        QRect rect(x, y, 16, 16);
+        tileNames << QString("tile_%1").arg(i);
+        tiles << pixmap.copy(rect);
+    }
+
+    tileBar->populateList(tileNames, tiles);
+}
+
+void HDF5Handler::saveRoom(int id, QString name, QVector<QVector<int>> tileIDs, QVector<QVector<int>> mobIDs)
+{
+    lvl::Room newRoom(id, name.toStdString(), 64, 64);
+    for (int row = 0; row < 64; row++) 
+    {
+        for (int col = 0; col < 64; col++) 
+        {
+            newRoom.placeTile({col,row}, tileIDs[row][col]);
+            //newRoom->placeEnemy(pos, mobIDs[row][col]);
+        }
+    }
+    std::vector<lvl::Room>& roomsList = m_Level.getRooms();
+    roomsList.push_back(newRoom);
+    m_Level.saveChanges("./level.h5");
+}
+
+int HDF5Handler::getMaxID()
+{
+    std::vector<lvl::Room>& roomsList = m_Level.getRooms();
+    lvl::Room lastRoom = roomsList.back();
+    return lastRoom.getId();
+}
+
+}
\ No newline at end of file
diff --git a/editor/src/HDF5Handler.hpp b/editor/src/HDF5Handler.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4000cce8b9f0034a84d9496afe0e134dc984f691
--- /dev/null
+++ b/editor/src/HDF5Handler.hpp
@@ -0,0 +1,56 @@
+#pragma once
+#include <QImage>
+#include <QPixmap>
+#include <level.hpp>
+#include <room.hpp>
+#include "TileBar.hpp"
+#include <QMessageBox>
+
+namespace editor
+{
+
+class HDF5Handler
+{
+
+public:
+    /**
+    * @brief Create a new HDF5Handler (main interface with liblvl library)
+    */
+    HDF5Handler();
+
+    /**
+    * @brief Create a new HDF5Handler (main interface with liblvl library)
+    */
+    HDF5Handler(std::filesystem::path path);
+
+    /**
+    * @brief destructor for HDF5Handler, default
+    */
+    ~HDF5Handler() = default;
+
+    /**
+    * @brief loads the tilesheet and puts tiles into TileBar
+    * @param tileBar pointer to the TileBar to show the tiles in
+    */
+    void loadTilesheet(TileBar* tileBar) const;
+
+    /**
+    * @brief saves configured room to HDF5
+    * @param id ID of the room, has to be unique!
+    * @param name Name of the room
+    * @param tileIDs 2D QVector of the tileIDs
+    * @param mobIDs 2D QVector of the tileIDs
+    */
+    void saveRoom(int id, QString name, QVector<QVector<int>> tileIDs, QVector<QVector<int>> mobIDs);
+
+    /**
+    * @brief find maximum room-ID in current HDF5-file
+    * @return highest room-ID
+    */
+    int getMaxID();
+
+private:
+    lvl::Level m_Level;
+};
+
+} // editor
\ No newline at end of file
diff --git a/editor/src/MainWindow.cpp b/editor/src/MainWindow.cpp
index bf0ed0ad41e25abcbbe083b54dc8954fc90a5c28..9451217cef6f15c4a83f5f3f67cdbf2991554e89 100644
--- a/editor/src/MainWindow.cpp
+++ b/editor/src/MainWindow.cpp
@@ -16,10 +16,24 @@ MainWindow::MainWindow(DialogSelection selected, const std::filesystem::path& pa
     QWidget* centralWidget = new QWidget(this);
     QHBoxLayout* mainLayout = new QHBoxLayout;
 
+    if (QFile::exists("./level.h5"))
+    {
+        std::filesystem::path path = "./level.h5";
+        HDF5Handler handler = HDF5Handler(path);
+        m_ID = handler.getMaxID() + 1;
+        std::cout << m_ID << std::endl;
+    } else
+    {
+        m_ID = 2;
+    }
+
     // Create the menu bar
     QMenuBar* menuBar = new QMenuBar(this);
     QMenu* fileMenu = menuBar->addMenu("File");
-    QMenu* settingsMenu = menuBar->addMenu("Settings");
+    //QMenu* settingsMenu = menuBar->addMenu("Settings");
+    QAction* saveRoomAction = new QAction("Save Room", this);
+    connect(saveRoomAction, &QAction::triggered, this, &MainWindow::saveLevel);
+    fileMenu->addAction(saveRoomAction);
     QAction* quitAction = new QAction("Quit", this);
     connect(quitAction, &QAction::triggered, this, &MainWindow::close);
     fileMenu->addAction(quitAction);
@@ -31,15 +45,8 @@ MainWindow::MainWindow(DialogSelection selected, const std::filesystem::path& pa
     m_leftWidget = leftWidget;
     connect(leftWidget, &editor::TileBar::itemClicked, this, &MainWindow::handleTileBarClick);
 
-    //temporary example, replace with real list of tileset
-    QStringList itemsLeft;
-    QList<QPixmap> pixmapsLeft;
-    for (int i = 1; i <= 100; ++i)
-    {
-        itemsLeft << QString("Item %1").arg(i);
-        pixmapsLeft << QPixmap("./editor/assets/images.png");
-    }
-    leftWidget->populateList(itemsLeft, pixmapsLeft);
+    const HDF5Handler handler;
+    handler.loadTilesheet(m_leftWidget);
 
     // Center grid
     CenterGrid* middleWidget = new CenterGrid(this);
@@ -72,9 +79,6 @@ MainWindow::MainWindow(DialogSelection selected, const std::filesystem::path& pa
     centralWidget->setLayout(mainLayout);
     setCentralWidget(centralWidget);
 
-    //testing centerGrid buttons
-    middleWidget->setCurrentSprite(QString::fromStdString("from MainWindow"));
-
     //initialize middleWidget as fully custom board
     middleWidget->drawPreset(5);
 }
@@ -83,7 +87,7 @@ void MainWindow::handleTileBarClick(int index, int id)
 {
     if (id == 0) 
     {
-        m_centerGrid->setCurrentSprite(m_leftWidget->getPixmapByIndex(index));
+        m_centerGrid->setCurrentSprite(m_leftWidget->getPixmapByIndex(index), index);
     } else 
     {
         QMessageBox::StandardButton confirmationPopup;
@@ -100,5 +104,26 @@ void MainWindow::handleTileBarClick(int index, int id)
     }
 }
 
+void MainWindow::saveLevel() 
+{
+    QVector<QVector<int>> tileIDs = m_centerGrid->getTileIDs();
+    QVector<QVector<int>> mobIDs;
+    QString name = "testlevel1234";
+
+    if (QFile::exists("./level.h5")) 
+    {
+        std::cout << "using new handler" << std::endl;
+        std::filesystem::path path = "./level.h5";
+        HDF5Handler handler = HDF5Handler(path);
+        handler.saveRoom(m_ID, name, tileIDs, mobIDs);
+    } else 
+    {
+        std::cout << "using default handler" << std::endl;
+        HDF5Handler handler = HDF5Handler();
+        handler.saveRoom(m_ID, name, tileIDs, mobIDs);
+    }
+    m_ID++;
+}
+
 }
 
diff --git a/editor/src/MainWindow.hpp b/editor/src/MainWindow.hpp
index de730ae106bde7d3875903baf6869a909407962f..adb32c0f47cbea46b02771433a649cf14d1220ae 100644
--- a/editor/src/MainWindow.hpp
+++ b/editor/src/MainWindow.hpp
@@ -13,6 +13,7 @@
 #include "StartupDialog.hpp"
 #include "CenterGrid.hpp"
 #include "TileBar.hpp"
+#include "HDF5Handler.hpp"
 
 
 namespace editor
@@ -42,6 +43,18 @@ private slots:
   void handleTileBarClick(int index, int id);
 
 private:
+
+  /**
+  * @brief Saves room to HDF5 when called in menu
+  */
+  void saveLevel();
+
+  /**
+  * @brief Converts 2D QVector to 1D std::vector for saving
+  * @return std::vector<int> 1D std::vector with tileIDs that can be saved in HDF5
+  */
+  std::vector<int> flatten(const QVector<QVector<int>>& input);
+
   /**
   * @brief Pointer to the centerGrid 
   */
@@ -52,6 +65,11 @@ private:
   */
   TileBar* m_leftWidget;
 
+  /**
+  * @brief Room ID to use for saving next room
+  */
+  int m_ID;
+
 };
 
 } // editor