diff --git a/CMakeLists.txt b/CMakeLists.txt
index 94f4f56fbccc8091b8093e3b2107c56e97d01cfe..593dc285ecf55564704b46a637189892eeaf8171 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,6 +47,12 @@ file(GLOB_RECURSE ADVANCED_WARS_SOURCES
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_BUILD_TYPE Debug)
+
+set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Wpedantic")
+set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Wpedantic")
+
+add_definitions(-DDEBUG)
 
 # Compiler-Warnungen aktivieren
 if(MSVC)
@@ -59,7 +65,8 @@ endif()
 set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/assets)
 set(OUTPUT_ASSETS_DIR ${CMAKE_CURRENT_BINARY_DIR}/assets)
 file(MAKE_DIRECTORY ${OUTPUT_ASSETS_DIR})
-file(GLOB FONT_FILES ${ASSETS_DIR}/*.ttf)
+file(GLOB FONT_FILES ${ASSETS_DIR}/*.TTF)
+file(GLOB IMAGE_FILES ${ASSETS_DIR}/*.png)
 
 # Executable erstellen
 add_executable(advanced_wars ${ADVANCED_WARS_SOURCES})
@@ -78,6 +85,14 @@ foreach(FONT ${FONT_FILES})
     )
 endforeach()
 
+foreach(IMAGE ${IMAGE_FILES})
+    add_custom_command(
+            TARGET advanced_wars PRE_BUILD
+            COMMAND ${CMAKE_COMMAND} -E copy ${IMAGE} ${OUTPUT_ASSETS_DIR}
+            COMMENT "Kopiere Image: ${IMAGE} nach ${OUTPUT_ASSETS_DIR}"
+    )
+endforeach()
+
 set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH})
 
 # Plattform-spezifische Konfiguration
@@ -127,4 +142,4 @@ else()
         box2d
         m
     )
-endif()
\ No newline at end of file
+endif()
diff --git a/README.md b/README.md
index 8e5bcd0f74eb02bafe338d75ed3e513d8e39bcff..e464b3acdb696833c43b9cfd88279d0063da4246 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,31 @@
 4. Visual Studio erkennt automatisch das CMake-Projekt
 5. Build über "Build All" ausführen
 
+#### Falls Syntax errors
+
+1. Erstelle .vscode/c_cpp_properties.json Datei
+2. Füge die folgende JSON so oder so ähnlich ein:
+
+```json
+{
+    "configurations": [
+        {
+            "name": "Fedora",
+            "includePath": [
+                "/usr/include",
+                "/usr/include/SDL2"
+            ],
+            "defines": [],
+            "intelliSenseMode": "linux-gcc-x64",
+            "compilerPath": "/usr/bin/gcc",
+            "cStandard": "c17",
+            "cppStandard": "c++17"
+        }
+    ],
+    "version": 4
+}
+```
+
 ## Build-Optionen
 
 CMake kann mit verschiedenen Optionen konfiguriert werden:
diff --git a/src/assets/ARCADECLASSIC.TTF b/src/assets/ARCADECLASSIC.TTF
new file mode 100644
index 0000000000000000000000000000000000000000..394a9f781cedaa283a11b3b8b43c9006f4e5bac7
Binary files /dev/null and b/src/assets/ARCADECLASSIC.TTF differ
diff --git a/src/assets/main_background.png b/src/assets/main_background.png
new file mode 100644
index 0000000000000000000000000000000000000000..5958dc0d0a7144697dece04db5dc2a1646088207
Binary files /dev/null and b/src/assets/main_background.png differ
diff --git a/src/engine.cpp b/src/engine.cpp
index 21d679a519ec5749ada5fa457eaaa97bd0605330..1eb0c0f4f4a67e2363b503b5910bb557943d4563 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -1,12 +1,15 @@
 #include "engine.hpp"
+#include "SDL_events.h"
 #include "scene.hpp"
 #include "spritesheet.hpp"
 #include "window.hpp"
 #include <SDL.h>
 #include <SDL_image.h>
 #include <SDL_render.h>
+#include <deque>
+#include <memory>
+#include <optional>
 #include <stdexcept>
-#include <vector>
 
 namespace advanced_wars
 {
@@ -17,15 +20,86 @@ Engine::Engine(Window& window) : window(window), quit(false)
     this->sdl_renderer = SDL_CreateRenderer(
         this->window.sdl_window(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
 
-    if (sdl_renderer == nullptr)
-    {
-        throw std::runtime_error("SDL could not generate renderer: " + std::string(SDL_GetError()));
+  int imgFlags = IMG_INIT_PNG;
+  if (!(IMG_Init(imgFlags) & imgFlags)) {
+    throw std::runtime_error(
+        "SDL_image could not initialize! SDL_image Error: " +
+        std::string(IMG_GetError()));
+  }
+
+  this->sdl_renderer =
+      SDL_CreateRenderer(this->window.sdl_window(), -1,
+                         SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+
+  if (sdl_renderer == nullptr) {
+    throw std::runtime_error("SDL could not generate renderer: " +
+                             std::string(SDL_GetError()));
+  }
+}
+
+std::deque<SDL_Event> &Engine::events() { return this->_events; }
+
+void Engine::push_scene(std::shared_ptr<Scene> scene) {
+  this->scenes.push_back(scene);
+}
+
+void Engine::return_to_menu() {
+  // TODO: discuss if we outsource this to a separate function
+  // clear everything except the first scene
+  while (this->scenes.size() > 1) {
+    this->scenes.pop_back();
+  }
+}
+
+
+std::optional<std::shared_ptr<Scene>> Engine::pop_scene() {
+  if (this->scenes.empty()) {
+    return std::nullopt;
+  }
+    std::shared_ptr<Scene> tmp = scenes.back();
+    this->scenes.pop_back();
+
+    return tmp;
+}
+
+void Engine::set_spritesheet(Spritesheet spritesheet) {
+  this->spritesheet = spritesheet;
+}
+
+void Engine::pump() {
+  SDL_Event e;
+  while (SDL_PollEvent(&e)) {
+    if (e.type == SDL_QUIT) {
+      this->quit = true;
+    } else {
+      this->_events.push_back(e);
     }
 }
 
-void Engine::set_scene(Scene& scene)
-{
-    this->scene = &scene;
+void Engine::exit() { this->quit = true; }
+
+bool Engine::exited() { return this->quit; }
+
+void Engine::render() {
+  if (SDL_RenderClear(this->sdl_renderer) != 0) {
+    throw std::runtime_error("Could not clear renderer: " +
+                             std::string(SDL_GetError()));
+  }
+
+  if (scenes.empty()) {
+    SDL_RenderPresent(this->sdl_renderer);
+    return;
+  }
+
+  std::shared_ptr<Scene> currentScene = scenes.back();
+  if (!currentScene) {
+    SDL_RenderPresent(this->sdl_renderer);
+    return;
+  }
+
+  currentScene->render(this);
+
+  SDL_RenderPresent(this->sdl_renderer);
 }
 
 void Engine::set_spritesheet(Spritesheet& spritesheet)
diff --git a/src/engine.hpp b/src/engine.hpp
index 3bc80efd1e77db45f922bdf3a60594425fd99a24..4906923df6c0a9356ee78849e580d444ed9a5a67 100644
--- a/src/engine.hpp
+++ b/src/engine.hpp
@@ -1,16 +1,21 @@
 #pragma once
 
+#include "SDL_events.h"
 #include "scene.hpp"
 #include "spritesheet.hpp"
 #include "window.hpp"
 #include <SDL.h>
 #include <SDL_render.h>
+#include <deque>
+#include <memory>
 #include <optional>
-#include <vector>
 
 namespace advanced_wars
 {
 
+// Forward declaration
+class Scene;
+
 /**
  * @brief The main window of the game
  */
@@ -24,9 +29,17 @@ class Engine
 
         bool exited();
 
-        void pump();
+  void exit();
+
+  void pump();
+
+  void push_scene(std::shared_ptr<Scene> scene);
+
+  std::optional<std::shared_ptr<Scene>> pop_scene();
+
+  void return_to_menu();
 
-        void set_scene(Scene& scene);
+  std::deque<SDL_Event> &events();
 
         void set_spritesheet(Spritesheet& spritesheet);
 
diff --git a/src/level.cpp b/src/level.cpp
index 9313b6063a2c0382f8ac25d513a076b493aaa15f..9597806ebc181666b86658e3da0e83daf061447d 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -8,16 +8,19 @@
 #include <SDL.h>
 #include <iostream>
 #include <string>
+#include "ui/pausemenu.hpp"
+#include "ui/contextmenu.hpp"
 
-namespace advanced_wars
-{
+namespace advanced_wars {
 
 Level::Level(
     std::string name, int width, int height, std::vector<Tile> tiles,
     std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects)
-    : name(name), width(width), height(height), tiles(tiles), id(0)
+    : name(name), width(width), height(height), tiles(tiles), id(0), context_menu(ContextMenu()), context_menu_active(false)
 {
 
+    context_menu.setOptions({"Move", "Info", "Wait"});
+
     for (Building building : buildings)
     {
         this->add_building(building);
@@ -46,7 +49,8 @@ void Level::render(Engine& engine, std::vector<SDL_Event>& events)
     // Iterate over all events
     while (!events.empty())
     {
-        events.erase(events.begin());
+        handleEvent(engine, engine->events().at(0));
+        engine->events().pop_front();
     }
 
     // Tiles
@@ -92,8 +96,48 @@ void Level::render(Engine& engine, std::vector<SDL_Event>& events)
     {
         std::cout << "Could not set render draw color: " << SDL_GetError() << std::endl;
     }
+
+    SDL_RenderClear(engine->renderer());
+
+    if(context_menu_active) {
+      context_menu.render(engine);
+    }
 }
 
+void Level::handleEvent(Engine *engine, SDL_Event &event) {
+  // Handle events for the level
+  if (event.type == SDL_KEYDOWN) {
+    if (event.key.keysym.sym == SDLK_ESCAPE) {
+      // Pause the game
+      std::cout << "Pausing game..." << std::endl;
+      SDL_Texture *currentTexture = SDL_CreateTexture(engine->renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 800, 600);
+
+      PauseMenu pauseMenu(0, currentTexture);
+      engine->push_scene(std::make_shared<PauseMenu>(pauseMenu));  
+    }
+    if(context_menu_active){
+       if(event.key.keysym.sym == SDLK_DOWN) {
+      context_menu.handleEvent(event);
+    }
+    if(event.key.keysym.sym == SDLK_UP) {
+      context_menu.handleEvent(event);
+    }
+    if(event.key.keysym.sym == SDLK_RETURN) {
+      if(context_menu.getSelectedOption() == "Wait"){
+        context_menu_active = false;
+      }
+    }
+   
+    }
+
+  }
+  if(event.type == SDL_MOUSEBUTTONDOWN) {
+      context_menu.update(event.button.x, event.button.y);
+      context_menu_active = true;
+    }
+}
+
+
 int Level::add_building(Building building)
 {
     buildings.insert({id, building});
@@ -142,4 +186,5 @@ Effect Level::remove_effect(int id)
     return value;
 }
 
-} // namespace advanced_wars
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/level.hpp b/src/level.hpp
index bb2db20d92180ca1eba34f44beb6826143b04cbd..33122616451998a5a2c069ca7601667f0aefb4c5 100644
--- a/src/level.hpp
+++ b/src/level.hpp
@@ -10,6 +10,7 @@
 #include <string>
 #include <unordered_map>
 #include <vector>
+#include "ui/contextmenu.hpp"
 
 namespace advanced_wars
 {
@@ -26,6 +27,8 @@ class Level : public Scene
 
         void render(Engine& engine, std::vector<SDL_Event>& events);
 
+        void handleEvent(Engine *engine, SDL_Event &event);
+
         int add_building(Building building);
 
         Building remove_building(int id);
@@ -48,6 +51,9 @@ class Level : public Scene
         std::unordered_map<int, Unit>     units;
         std::unordered_map<int, Effect>   effects;
 
+        ContextMenu context_menu;
+        bool context_menu_active;
+
         int id;
 };
 
diff --git a/src/main.cpp b/src/main.cpp
index 2ff1123fc4a23ed7bd73fa6350fb8f8be1691d9d..82e36fce730948141faabd74002d104952244bc7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,8 +1,10 @@
 #include "building.hpp"
 #include "effect.hpp"
 #include "engine.hpp"
-#include "level.hpp"
 #include "spritesheet.hpp"
+#include "ui/menu.hpp"
+#include "ui/contextmenu.hpp"
+#include <memory>
 #include "tile.hpp"
 #include "unit.hpp"
 #include "window.hpp"
@@ -32,6 +34,19 @@ int main()
     Window window("Advanced Wars", 960, 960);
 
     Engine engine(window);
+  // render main menu
+
+  std::shared_ptr<Menu> menu = std::make_shared<Menu>(0);
+  std::shared_ptr<ContextMenu> context_menu = std::make_shared<ContextMenu>();
+  context_menu->setOptions({"Move", "Info", "Wait"});
+
+
+  std::string basePath = SDL_GetBasePath();
+  std::string relativePath = "assets/main_background.png";
+  std::string fullPath = basePath + relativePath;
+  menu->loadBackground(engine.renderer(), fullPath.c_str());
+
+  engine.push_scene(menu);
 
     // Construct a level
     std::vector<Tile> tiles;
@@ -42,6 +57,8 @@ int main()
             tiles.push_back(Tile(TileId::PLAIN, x, y));
         }
     }
+    
+  engine.set_spritesheet(spritesheet);
 
     // Fill the edges with water
     for (size_t n = 0; n < 20; n++)
diff --git a/src/scene.hpp b/src/scene.hpp
index d61edefc09a188b0b3094a66fad83a8ea493f123..59067c232872416d1dd2b2a93f116064b831a84b 100644
--- a/src/scene.hpp
+++ b/src/scene.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
+#include "engine.hpp"
 #include <SDL.h>
-#include <vector>
 
 namespace advanced_wars
 {
@@ -14,4 +14,5 @@ class Scene
     public:
         virtual void render(Engine& engine, std::vector<SDL_Event>& events) = 0;
 };
+
 } // namespace advanced_wars
diff --git a/src/spritesheet.cpp b/src/spritesheet.cpp
index c5ff86870e20e5fed39d7049ca5db401d63255cd..1a93c96fb55fbeb553b2d4acbb8d023f9204199f 100644
--- a/src/spritesheet.cpp
+++ b/src/spritesheet.cpp
@@ -7,7 +7,8 @@
  */
 
 #include "spritesheet.hpp"
-#include "SDL_pixels.h"
+#include <SDL_render.h>
+#include "SDL_surface.h"
 #include "engine.hpp"
 #include "highfive/H5File.hpp"
 #include <SDL_image.h>
diff --git a/src/spritesheet.hpp b/src/spritesheet.hpp
index 7d82c39cbffdea9cd511cb1ea76fd8de94d5abcd..c6ae316725e2d6f088be7052cd904277efde047f 100644
--- a/src/spritesheet.hpp
+++ b/src/spritesheet.hpp
@@ -8,6 +8,7 @@
 
 #pragma once
 
+#include <SDL_render.h>
 #include <SDL.h>
 #include <SDL_render.h>
 #include <string>
diff --git a/src/ui/contextmenu.cpp b/src/ui/contextmenu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8bae5ff334cb15200d3cac4f296e266f871960c9
--- /dev/null
+++ b/src/ui/contextmenu.cpp
@@ -0,0 +1,83 @@
+#include "contextmenu.hpp"
+#include <iostream>
+#include <SDL_ttf.h>
+
+namespace advanced_wars {
+
+    ContextMenu::ContextMenu()
+        : selectedOption(0) {}
+
+    ContextMenu::~ContextMenu() {}
+
+    void ContextMenu::setOptions(const std::vector<std::string>& newOptions) {
+        options = newOptions;
+        selectedOption = 0; // Reset auf die erste Option
+    }
+
+    void ContextMenu::render(Engine* engine) {
+        if (!options.empty()) {
+            if (TTF_Init() == -1) {
+                std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+                return;
+            }
+
+            std::string basePath = SDL_GetBasePath();
+            std::string relativePath = "assets/ARCADECLASSIC.TTF";
+            std::string fullPath = basePath + relativePath;
+            TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 16);
+            if (!font) {
+                std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
+                return;
+            }
+
+            SDL_Color white = {255, 255, 255, 255};
+            SDL_Color yellow = {192, 255, 0, 255};
+
+            int spacing = 20; // Abstand zwischen den Optionen
+
+            //box around options
+            SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 255, 255);
+            SDL_Rect box = {x, y - 3, 50, static_cast<int>(options.size() * spacing)};
+            SDL_RenderFillRect(engine->renderer(), &box);
+
+            SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255);
+            
+            for (size_t i = 0; i < options.size(); ++i) {
+                SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white);
+                if (!textSurface) {
+                    continue;
+                }
+
+                SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine->renderer(), textSurface);
+                SDL_Rect textRect = {x+10, y + static_cast<int>(i * spacing), textSurface->w, textSurface->h};
+                SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect);
+
+                SDL_DestroyTexture(textTexture);
+                SDL_FreeSurface(textSurface);
+            }
+
+            TTF_CloseFont(font);
+            TTF_Quit();
+        }
+    }
+
+    void ContextMenu::handleEvent(SDL_Event& event) {
+        if (event.type == SDL_KEYDOWN) {
+            if (event.key.keysym.sym == SDLK_DOWN) {
+                selectedOption = (selectedOption + 1) % options.size();
+            } else if (event.key.keysym.sym == SDLK_UP) {
+                selectedOption = (selectedOption - 1 + options.size()) % options.size();
+            }
+        }
+    }
+
+    std::string ContextMenu::getSelectedOption() {
+        return options[selectedOption];
+    }
+
+    void ContextMenu::update(int x, int y) {
+        this->x = x;
+        this->y = y;
+    }
+
+}
diff --git a/src/ui/contextmenu.hpp b/src/ui/contextmenu.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..94b095f928fa6a4a67f691e22b3799b8ac767599
--- /dev/null
+++ b/src/ui/contextmenu.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <SDL.h>
+#include <vector>
+#include <string>
+#include "../scene.hpp"
+#include "../engine.hpp"
+
+namespace advanced_wars {
+
+class ContextMenu : public Scene {
+private:
+    size_t selectedOption;
+    std::vector<std::string> options;
+    int x;
+    int y;
+
+public:
+    ContextMenu();    
+
+    void setOptions(const std::vector<std::string>& newOptions);
+
+    void render(Engine* engine) override;
+
+    void handleEvent(SDL_Event& event);
+
+    void update(int x, int y);
+
+    std::string getSelectedOption();
+
+    ~ContextMenu();
+};
+
+}
\ No newline at end of file
diff --git a/src/ui/menu.cpp b/src/ui/menu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9dafaffd1dfc4c2e92ef8dc2a833d8a8bcdcc013
--- /dev/null
+++ b/src/ui/menu.cpp
@@ -0,0 +1,168 @@
+#include "menu.hpp"
+#include <SDL.h>
+#include <SDL_image.h>
+#include <SDL_ttf.h>
+#include <iostream>
+#include <string>
+#include "../level.hpp"
+#include "../building.hpp"
+#include "../unit.hpp"
+#include "../tile.hpp"
+#include "../spritesheet.hpp"
+
+namespace advanced_wars {
+
+Menu::Menu(int selectedOption)
+    : selectedOption(selectedOption),
+      options({"Start Game", "Options", "Exit"}), backgroundTexture(nullptr) {
+  if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) {
+    std::cerr << "Failed to initialize SDL_image: " << IMG_GetError()
+              << std::endl;
+  }
+}
+
+Menu::~Menu() {
+  if (backgroundTexture) {
+    SDL_DestroyTexture(backgroundTexture);
+  }
+  IMG_Quit();
+};
+
+void Menu::render(Engine *engine) {
+
+  // Iterate over all events
+  while (!engine->events().empty()) {
+    SDL_Event event = engine->events().at(0);
+    engine->events().pop_front();
+    handleEvent(engine, event);
+  }
+
+  if (backgroundTexture) {
+    SDL_RenderCopy(engine->renderer(), backgroundTexture, nullptr, nullptr);
+  } else {
+    SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255);
+    SDL_RenderClear(engine->renderer());
+  }
+
+  if (TTF_Init() == -1) {
+    std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+    return;
+  }
+
+  std::string basePath = SDL_GetBasePath();
+  std::string relativePath = "assets/ARCADECLASSIC.TTF";
+  std::string fullPath = basePath + relativePath;
+  TTF_Font *titleFont = TTF_OpenFont(fullPath.c_str(), 48);
+  if (!titleFont) {
+    std::cerr << "Failed to load title font: " << fullPath << TTF_GetError()
+              << std::endl;
+    return;
+  }
+
+  TTF_Font *menuFont = TTF_OpenFont(fullPath.c_str(), 24);
+  if (!menuFont) {
+    TTF_CloseFont(titleFont);
+    std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError()
+              << std::endl;
+    return;
+  }
+
+  SDL_Color white = {255, 255, 255, 255};
+  SDL_Color yellow = {255, 255, 0, 255};
+
+  SDL_Surface *titleSurface =
+      TTF_RenderText_Solid(titleFont, "Advanced Wars", white);
+  if (titleSurface) {
+    SDL_Texture *titleTexture =
+        SDL_CreateTextureFromSurface(engine->renderer(), titleSurface);
+    SDL_Rect titleRect = {static_cast<int>((800 - titleSurface->w) / 2), 50,
+                          titleSurface->w, titleSurface->h};
+    SDL_RenderCopy(engine->renderer(), titleTexture, nullptr, &titleRect);
+    SDL_DestroyTexture(titleTexture);
+    SDL_FreeSurface(titleSurface);
+  }
+
+  for (size_t i = 0; i < options.size(); ++i) {
+    SDL_Surface *textSurface = TTF_RenderText_Solid(
+        menuFont, options[i].c_str(), (i == selectedOption) ? yellow : white);
+    if (!textSurface) {
+      continue;
+    }
+
+    SDL_Texture *textTexture =
+        SDL_CreateTextureFromSurface(engine->renderer(), textSurface);
+    SDL_Rect textRect = {static_cast<int>((800 - textSurface->w) / 2),
+                         static_cast<int>(150 + i * 50), textSurface->w,
+                         textSurface->h};
+    SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect);
+
+    SDL_DestroyTexture(textTexture);
+    SDL_FreeSurface(textSurface);
+  }
+
+  TTF_CloseFont(titleFont);
+  TTF_CloseFont(menuFont);
+  TTF_Quit();
+
+  SDL_RenderPresent(engine->renderer());
+}
+
+void Menu::handleEvent(Engine *engine, SDL_Event &event) {
+  if (event.type == SDL_KEYDOWN) {
+    if (event.key.keysym.sym == SDLK_DOWN) {
+      selectedOption = (selectedOption + 1) % options.size();
+    } else if (event.key.keysym.sym == SDLK_UP) {
+      selectedOption = (selectedOption - 1 + options.size()) % options.size();
+    } else if (event.key.keysym.sym == SDLK_RETURN) {
+      if (options[selectedOption] == "Exit") {
+        std::cout << "Exiting game..." << std::endl;
+        engine->exit();
+      } else if (options[selectedOption] == "Start Game") {
+        std::cout << "Starting game..." << std::endl;
+
+        /* TODO REMOVE THIS BOILERPLATE CODE BEFORE MERGE */
+
+        Level level("Osnabrück", 20, 20, std::vector<Tile>(),
+        std::vector<Building>(), std::vector<Unit>());
+
+        engine->push_scene(std::make_shared<advanced_wars::Level>(level));
+
+        std::string basePath = SDL_GetBasePath();
+        std::string relativePath = "assets/main_background.png";
+        std::string fullPath = basePath + relativePath;
+        Spritesheet spritesheet(fullPath, *engine);
+
+        engine->set_spritesheet(spritesheet);
+
+        /* END OF BOILERPLATE CODE */
+
+      } else if (options[selectedOption] == "Options") {
+        std::cout << "Opening options..." << std::endl;
+      }
+    }
+  }
+}
+
+void Menu::loadBackground(SDL_Renderer *renderer,
+                          const std::string &imagePath) {
+  // Lade das Hintergrundbild
+  SDL_Surface *backgroundSurface = IMG_Load(imagePath.c_str());
+  if (!backgroundSurface) {
+    std::cerr << "Failed to load background image: " << IMG_GetError()
+              << std::endl;
+    return;
+  }
+
+  // Erstelle eine Textur aus der Oberfläche und speichere sie als
+  // Klassenmitglied
+  backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface);
+  SDL_FreeSurface(backgroundSurface); // Oberfläche freigeben, da sie nicht mehr
+                                      // benötigt wird
+
+  if (!backgroundTexture) {
+    std::cerr << "Failed to create background texture: " << SDL_GetError()
+              << std::endl;
+  }
+}
+
+} // namespace advanced_wars
diff --git a/src/ui/menu.hpp b/src/ui/menu.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..43f84d081e9611a251a5a2430d35d9dde9771ffa
--- /dev/null
+++ b/src/ui/menu.hpp
@@ -0,0 +1,86 @@
+#pragma once
+
+#include "../scene.hpp"
+#include <SDL.h>
+#include <array>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace advanced_wars {
+
+/**
+ * @class Menu
+ * @brief Represents the main menu of the game, allowing navigation between different options.
+ * 
+ * This menu provides three selectable options:
+ * - "Start Game": Begins a new game session.
+ * - "Options": Opens the game settings.
+ * - "Exit": Closes the application.
+ */
+class Menu : public Scene {
+private:
+  size_t selectedOption; ///< Index of the currently selected menu option.
+  std::array<std::string, 3> options; ///< The available menu options.
+  SDL_Texture *backgroundTexture; ///< Pointer to the background texture (if any).
+
+public:
+  /**
+   * @brief Constructs the Menu with an initial selected option.
+   * 
+   * Initializes the menu with the available options and sets the currently
+   * selected option based on the given index.
+   * 
+   * @param selectedOption The index of the initially selected menu option.
+   */
+  Menu(int selectedOption);
+
+  /**
+   * @brief Renders the menu on the screen.
+   * 
+   * This method clears the screen, draws the background (if available),
+   * renders the menu title, and displays the selectable options. The currently
+   * selected option is highlighted in a different color.
+   * 
+   * @param engine Pointer to the game engine, used for rendering.
+   */
+  void render(Engine *engine) override;
+
+  /**
+   * @brief Handles user input events for menu navigation.
+   * 
+   * This method processes keyboard input to navigate through the menu options.
+   * - **Arrow Down (`SDLK_DOWN`)**: Moves the selection to the next option.
+   * - **Arrow Up (`SDLK_UP`)**: Moves the selection to the previous option.
+   * - **Enter (`SDLK_RETURN`)**: Confirms the selection:
+   *   - **"Start Game"**: Loads the game scene.
+   *   - **"Options"**: Opens the settings menu.
+   *   - **"Exit"**: Closes the application.
+   * 
+   * @param engine Pointer to the game engine, used to manage scenes.
+   * @param event The SDL event containing user input data.
+   */
+  void handleEvent(Engine *engine, SDL_Event &event);
+
+  /**
+   * @brief Loads a background image as a texture.
+   * 
+   * This method loads an image file, converts it into an SDL texture, and 
+   * assigns it as the menu's background. If the loading fails, an error is 
+   * logged, and the menu will display a plain black background instead.
+   * 
+   * @param renderer The SDL renderer used to create the texture.
+   * @param imagePath The file path to the background image.
+   */
+  void loadBackground(SDL_Renderer *renderer, const std::string &imagePath);
+
+  /**
+   * @brief Destroys the menu and releases resources.
+   * 
+   * Cleans up allocated resources, including the background texture (if loaded),
+   * and ensures that SDL_Image is properly shut down.
+   */
+  ~Menu();
+};
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/ui/pausemenu.cpp b/src/ui/pausemenu.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0dd592841e6e0fa352fca4b483d3e6e839dd5923
--- /dev/null
+++ b/src/ui/pausemenu.cpp
@@ -0,0 +1,118 @@
+#include "pausemenu.hpp"
+#include "../engine.hpp"
+#include <SDL_ttf.h>
+
+namespace advanced_wars {
+
+PauseMenu::PauseMenu(int selectedOption, SDL_Texture *backgroundTexture)
+    : selectedOption(selectedOption),
+      options({"Resume", "Options", "Exit"}), backgroundTexture(backgroundTexture) {
+  // Initialize SDL_ttf
+  if (TTF_Init() == -1) {
+    std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl;
+  }
+
+  if (!backgroundTexture) {
+    this->backgroundTexture = nullptr;
+  }
+}
+
+PauseMenu::~PauseMenu() {
+  if (backgroundTexture) {
+    SDL_DestroyTexture(backgroundTexture);
+    backgroundTexture = nullptr;
+  }
+  TTF_Quit();
+}
+
+void PauseMenu::render(Engine *engine) {
+
+  while (!engine->events().empty()) {
+    SDL_Event event = engine->events().at(0);
+    engine->events().pop_front();
+    handleEvent(engine, event);
+  }
+
+  SDL_Renderer *renderer = engine->renderer();
+
+  // Render the existing level
+  //engine->render();
+
+  // Render the dialog background
+  if (backgroundTexture) {
+    SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr);
+  }
+
+  if (TTF_Init() == -1) {
+    std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+    return;
+  }
+
+  // Render the dialog options on top of the background
+  std::string basePath = SDL_GetBasePath();
+  std::string relativePath = "assets/ARCADECLASSIC.TTF";
+  std::string fullPath = basePath + relativePath;
+
+  TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 24);
+  if (!font) {
+    std::cerr << "Failed to load menu font: " << fullPath << " " << TTF_GetError()
+              << std::endl;
+    return;
+  }
+
+  SDL_Color white = {255, 255, 255, 255};
+  SDL_Color yellow = {255, 255, 0, 255};
+
+  for (size_t i = 0; i < options.size(); ++i) {
+    SDL_Surface *textSurface = TTF_RenderText_Solid(
+        font, options[i].c_str(), (i == selectedOption) ? yellow : white);
+    SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
+    
+    SDL_Rect destRect = {100, static_cast<int>(100 + i * 50), textSurface->w, textSurface->h};  
+    SDL_RenderCopy(renderer, textTexture, nullptr, &destRect);
+
+    SDL_FreeSurface(textSurface);
+    SDL_DestroyTexture(textTexture);
+  }
+  TTF_CloseFont(font);
+  SDL_RenderPresent(renderer);
+}
+
+void PauseMenu::handleEvent(Engine *engine, SDL_Event &event) {
+  if (event.type == SDL_KEYDOWN) {
+    if (event.key.keysym.sym == SDLK_DOWN) {
+      selectedOption = (selectedOption + 1) % options.size();
+    } else if (event.key.keysym.sym == SDLK_UP) {
+      selectedOption = (selectedOption - 1 + options.size()) % options.size();
+    } else if (event.key.keysym.sym == SDLK_ESCAPE) {
+      std::cout << "Resuming game..." << std::endl;
+      engine->pop_scene();
+    } else if (event.key.keysym.sym == SDLK_RETURN) {
+      if (options[selectedOption] == "Exit") {
+        // exit into main menu
+        std::cout << "Exiting game..." << std::endl;
+        engine->return_to_menu();
+      } else if (options[selectedOption] == "Resume") {
+        // resume game
+        std::cout << "Resuming game..." << std::endl;
+        engine->pop_scene();
+      }
+    }
+
+  }
+  // Handle events for the pause menu
+}
+
+
+
+void PauseMenu::loadBackground(SDL_Renderer *renderer, const std::string &imagePath) {
+  SDL_Surface *surface = IMG_Load(imagePath.c_str());
+  if (!surface) {
+    std::cerr << "Failed to load image: " << IMG_GetError() << std::endl;
+    return;
+  }
+  backgroundTexture = SDL_CreateTextureFromSurface(renderer, surface);
+  SDL_FreeSurface(surface);
+}
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6dc2d2cec236d7d614e8d012ce2ce935675c233d
--- /dev/null
+++ b/src/ui/pausemenu.hpp
@@ -0,0 +1,92 @@
+#pragma once
+
+#include "../scene.hpp"
+#include <SDL.h>
+#include <array>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <SDL_image.h>
+#include <SDL_ttf.h>
+
+namespace advanced_wars {
+
+/**
+ * @class PauseMenu
+ * @brief A scene that represents the in-game pause menu.
+ * 
+ * The pause menu allows the player to:
+ * - **Resume**: Return to the current game scene.
+ * - **Options**: (Currently not implemented).
+ * - **Exit**: Return to the main menu.
+ * 
+ * The menu supports keyboard navigation and responds to user input.
+ */
+class PauseMenu : public Scene {
+private:
+  size_t selectedOption; ///< Index of the currently selected menu option.
+  std::array<std::string, 3> options; ///< The available pause menu options.
+  SDL_Texture *backgroundTexture; ///< Pointer to the background texture (if available).
+
+public:
+  /**
+   * @brief Constructs the pause menu with a background texture.
+   * 
+   * The pause menu initializes the menu options and stores the provided
+   * background texture. If no texture is provided, a default black background is used.
+   * 
+   * @param selectedOption The index of the initially selected menu option.
+   * @param backgroundTexture A pointer to the background texture (can be nullptr).
+   */
+  PauseMenu(int selectedOption, SDL_Texture *backgroundTexture);
+
+  /**
+   * @brief Renders the pause menu on the screen.
+   * 
+   * This method:
+   * - Draws the background (if available).
+   * - Displays the menu options with the currently selected option highlighted.
+   * - Presents the rendered frame to the screen.
+   * 
+   * @param engine Pointer to the game engine, used for rendering.
+   */
+  void render(Engine *engine) override;
+
+  /**
+   * @brief Handles user input events for menu navigation.
+   * 
+   * This method processes keyboard input to navigate and interact with the pause menu.
+   * - **Arrow Down (`SDLK_DOWN`)**: Moves the selection to the next option.
+   * - **Arrow Up (`SDLK_UP`)**: Moves the selection to the previous option.
+   * - **Escape (`SDLK_ESCAPE`)**: Resumes the game by removing the pause menu.
+   * - **Enter (`SDLK_RETURN`)**: Executes the selected option:
+   *   - **"Resume"**: Closes the pause menu and resumes the game.
+   *   - **"Exit"**: Returns to the main menu.
+   * 
+   * @param engine Pointer to the game engine, used to manage scenes.
+   * @param event The SDL event containing user input data.
+   */
+  void handleEvent(Engine *engine, SDL_Event &event);
+
+  /**
+   * @brief Loads a background image as a texture.
+   * 
+   * This method loads an image file, converts it into an SDL texture, and assigns it
+   * as the menu’s background. If the loading fails, an error is logged, and the menu
+   * will display a plain black background instead.
+   * 
+   * @param renderer The SDL renderer used to create the texture.
+   * @param imagePath The file path to the background image.
+   */
+  void loadBackground(SDL_Renderer *renderer, const std::string &imagePath);
+
+  /**
+   * @brief Destroys the pause menu and releases resources.
+   * 
+   * Cleans up allocated resources, including the background texture (if loaded),
+   * and ensures that SDL_ttf is properly shut down.
+   */
+  ~PauseMenu();
+};
+
+} // namespace advanced_wars
\ No newline at end of file