diff --git a/cmake/targets/CMakeLists.txt b/cmake/targets/CMakeLists.txt
index a5df8102..cf7871a6 100644
--- a/cmake/targets/CMakeLists.txt
+++ b/cmake/targets/CMakeLists.txt
@@ -6,14 +6,12 @@
 # Check for build target, or default. This is pretty much not guaranteed.
 if(NOT DEFINED DAWN_BUILD_TARGET)
   if(WIN32)
-    set(DAWN_BUILD_TARGET "target-helloworld-win32-glfw")
+    set(DAWN_BUILD_TARGET "target-rose-win32-glfw")
   elseif(UNIX AND NOT APPLE)
-    set(DAWN_BUILD_TARGET "target-helloworld-linux64-glfw")
+    set(DAWN_BUILD_TARGET "target-rose-linux64-glfw")
   endif()
 endif()
 
-# set(DAWN_BUILD_TARGET "target-helloworld-vita")
-
 # Now validate we have a build target for real
 if(NOT DEFINED DAWN_BUILD_TARGET)
   message(FATAL_ERROR "You need to define a DAWN_BUILD_TARGET")
diff --git a/cmake/targets/target-rose-linux64-glfw/CMakeLists.txt b/cmake/targets/target-rose-linux64-glfw/CMakeLists.txt
new file mode 100644
index 00000000..54b87713
--- /dev/null
+++ b/cmake/targets/target-rose-linux64-glfw/CMakeLists.txt
@@ -0,0 +1,9 @@
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+set(DAWN_BUILDING dawnrose CACHE INTERNAL ${DAWN_CACHE_TARGET})
+set(DAWN_TARGET_LINUX64 true CACHE INTERNAL ${DAWN_CACHE_TARGET})
+set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
+set(DAWN_TARGET_NAME "Rose" CACHE INTERNAL ${DAWN_CACHE_TARGET})
\ No newline at end of file
diff --git a/src/dawn/CMakeLists.txt b/src/dawn/CMakeLists.txt
index 5e93d2e7..2d87c2fe 100644
--- a/src/dawn/CMakeLists.txt
+++ b/src/dawn/CMakeLists.txt
@@ -26,6 +26,7 @@ target_sources(${DAWN_TARGET_NAME}
 # Subdirs
 add_subdirectory(asset)
 add_subdirectory(display)
+add_subdirectory(game)
 add_subdirectory(games)
 add_subdirectory(input)
 add_subdirectory(locale)
diff --git a/src/dawnosui/game/CMakeLists.txt b/src/dawn/game/CMakeLists.txt
similarity index 70%
rename from src/dawnosui/game/CMakeLists.txt
rename to src/dawn/game/CMakeLists.txt
index 07f25903..8ca94ca8 100644
--- a/src/dawnosui/game/CMakeLists.txt
+++ b/src/dawn/game/CMakeLists.txt
@@ -1,10 +1,10 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Sources
-target_sources(${DAWN_TARGET_NAME}
-  PRIVATE
-    DawnPokerGame.cpp
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    DawnGame.cpp
 )
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/DawnGame.cpp b/src/dawn/game/DawnGame.cpp
similarity index 87%
rename from src/dawnhelloworld/game/DawnGame.cpp
rename to src/dawn/game/DawnGame.cpp
index 149e66e7..3f337787 100644
--- a/src/dawnhelloworld/game/DawnGame.cpp
+++ b/src/dawn/game/DawnGame.cpp
@@ -1,43 +1,42 @@
-// Copyright (c) 2023 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "DawnGame.hpp"
-#include "scenes/HelloWorldScene.hpp"
-
-using namespace Dawn;
-
-DawnGame::DawnGame(DawnHost *host) :
-  host(host),
-  renderManager(this),
-  inputManager(this),
-  saveManager(this)
-{
-}
-
-int32_t DawnGame::init() {
-  this->assetManager.init();
-  this->renderManager.init();
-
-  this->scene = new HelloWorldScene(this);
-  
-  return DAWN_GAME_INIT_RESULT_SUCCESS;
-}
-
-int32_t DawnGame::update(float_t delta) {
-  this->assetManager.update();
-  this->inputManager.update();
-  this->timeManager.update(delta);
-
-  if(this->scene != nullptr) this->scene->update();
-  
-  this->renderManager.update();
-
-  return DAWN_GAME_UPDATE_RESULT_SUCCESS;
-}
-
-void DawnGame::sceneCutover(Scene *scene) {
-  if(scene == nullptr) scene = this->scene;
-  this->sceneToCutTo = scene;
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "DawnGame.hpp"
+
+using namespace Dawn;
+
+DawnGame::DawnGame(DawnHost *host) :
+  host(host),
+  renderManager(this),
+  inputManager(this),
+  saveManager(this)
+{
+}
+
+int32_t DawnGame::init() {
+  this->assetManager.init();
+  this->renderManager.init();
+
+  this->scene = dawnGameGetInitialScene(this);
+  
+  return DAWN_GAME_INIT_RESULT_SUCCESS;
+}
+
+int32_t DawnGame::update(float_t delta) {
+  this->assetManager.update();
+  this->inputManager.update();
+  this->timeManager.update(delta);
+
+  if(this->scene != nullptr) this->scene->update();
+  
+  this->renderManager.update();
+
+  return DAWN_GAME_UPDATE_RESULT_SUCCESS;
+}
+
+void DawnGame::sceneCutover(Scene *scene) {
+  if(scene == nullptr) scene = this->scene;
+  this->sceneToCutTo = scene;
 }
\ No newline at end of file
diff --git a/src/dawn/game/_DawnGame.hpp b/src/dawn/game/DawnGame.hpp
similarity index 69%
rename from src/dawn/game/_DawnGame.hpp
rename to src/dawn/game/DawnGame.hpp
index c9672ae2..444e6d9b 100644
--- a/src/dawn/game/_DawnGame.hpp
+++ b/src/dawn/game/DawnGame.hpp
@@ -22,12 +22,25 @@
 namespace Dawn {
   class DawnHost;
 
-  class IDawnGame {
-    protected:
-      // SceneItemComponentList componentList;
+  class DawnGame {
+    private:
+      Scene *sceneToCutTo = nullptr;
 
     public:
+      DawnHost *host;
       Scene *scene = nullptr;
+      AssetManager assetManager;
+      TimeManager timeManager;
+      RenderManager renderManager;
+      InputManager inputManager;
+      SaveManager saveManager;
+
+      /**
+       * Construct a new game instance.
+       * 
+       * @param host Host that executed this game instantiation.
+       */
+      DawnGame(DawnHost *host);
 
       /**
        * Initialize the game. This is performed by the host at a time that is
@@ -38,7 +51,7 @@ namespace Dawn {
        * @param host Pointer to the host that is running this game.
        * @return The game initialize result.
        */
-      virtual int32_t init() = 0;
+      int32_t init();
 
       /**
        * Performs a game update operation. This operation should occur exactly
@@ -52,7 +65,7 @@ namespace Dawn {
        * @param delta Time delta to tick the game by.
        * @return The game update result.
        */
-      virtual int32_t update(float_t delta) = 0;
+      int32_t update(float_t delta);
 
       /**
        * Changes to a new scene, will dispose the currently active scene as part
@@ -61,13 +74,15 @@ namespace Dawn {
        * 
        * @param scene Scene to cut over to.
        */
-      virtual void sceneCutover(Scene *scene) = 0;
-
-      /**
-       * Cleanup the memory of the DawnGame instance.
-       */
-      virtual ~IDawnGame() {
-
-      }
+      void sceneCutover(Scene *scene);
   };
+
+  /**
+   * Unimplemented by default, required by the game as the basic entry point 
+   * for which scene should be used by default.
+   * 
+   * @param game Game that is requesting this scene.
+   * @return Pointer to a scene that you wish to have as the default scene.
+   */
+  Scene * dawnGameGetInitialScene(DawnGame *game);
 }
\ No newline at end of file
diff --git a/src/dawn/save/SaveManager.cpp b/src/dawn/save/SaveManager.cpp
index ad33df71..c5dbaaa4 100644
--- a/src/dawn/save/SaveManager.cpp
+++ b/src/dawn/save/SaveManager.cpp
@@ -1,217 +1,217 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "SaveManager.hpp"
-#include "game/DawnGame.hpp"
-
-using namespace Dawn;
-
-SaveManager::SaveManager(DawnGame *game) {
-  this->game = game;
-}
-
-void SaveManager::saveFile() {
-  savedata_t value;
-
-  assertTrue(this->currentSaveSlot >= 0);
-  
-  // Update metadata
-  auto timestamp = this->game->timeManager.getTimestamp();
-  value.i64 = timestamp;
-  this->currentSave.set(SAVE_KEY_TIMESTAMP, value);
-  value.i16 = this->currentSaveSlot;
-  this->currentSave.set(SAVE_KEY_SLOT, value);
-
-  // Now open output buffer.
-  char filename[SAVE_MANAGER_FILENAME_LENGTH];
-  sprintf(filename, "savefile_%u.save", this->currentSaveSlot);
-  FILE *fptr = fopen(filename, "wb");
-  if(fptr == NULL) {
-    printf("Error opening %s\n", filename);
-    assertUnreachable();
-    return;
-  }
-
-  // Now begin buffering data. First we start with the common phrase, the engine
-  // version, the timestamp. In future we will store the MD5 here too.
-  char buffer[SAVE_MANAGER_BUFFER_LENGTH];
-  auto len = sprintf(buffer, "DE_SAVE|%s|%lld|", "1.00", timestamp);
-  fwrite(buffer, sizeof(char), len, fptr);
-
-  // Now buffer out the data, this is almost certain to change over time.
-  auto it = this->currentSave.values.begin();
-  while(it != this->currentSave.values.end()) {
-    uint8_t *buffer = (uint8_t *)&it->second;
-    char delim = '|';
-    fwrite(it->first.c_str(), sizeof(char), strlen(it->first.c_str()), fptr);
-    fwrite(&delim, sizeof(char), 1, fptr);
-    fwrite(buffer, sizeof(uint8_t), sizeof(savedata_t) / sizeof(uint8_t), fptr);
-    fwrite(&delim, sizeof(char), 1, fptr);
-    ++it;
-  }
-
-  // Buffering done, close the file buffer.
-  fclose(fptr);
-  this->currentSave.hasChanges = false;
-}
-
-enum SaveLoadResult SaveManager::loadFile() {
-  this->currentSave.reset();
-
-  assertTrue(this->currentSaveSlot >= 0);
-
-  // Load file
-  struct SaveFile temporaryFile;
-
-  char filename[SAVE_MANAGER_FILENAME_LENGTH];
-  sprintf(filename, "savefile_%u.save", this->currentSaveSlot);
-  FILE *fptr = fopen(filename, "rb");
-  if(fptr == NULL) {
-    return SAVE_LOAD_RESULT_FILE_NOT_PRESENT;
-  }
-
-  // Let's read how long the file is first.
-  fseek(fptr, 0, SEEK_END);
-  auto len = ftell(fptr);
-
-  // Now let's just ensure the file isn't too small, this starts by us making
-  // sure we have at least "DE_SAVE|%s|%lld|", the string is unknown length, 
-  // but we can be 100% sure of the rest of the file size. So we take
-  // 7+1+1+1+19+1=30
-  if(len < 30) {
-    fclose(fptr);
-    return SAVE_LOAD_RESULT_TOO_SMALL;
-  }
-  
-  // Rewind.
-  fseek(fptr, 0, SEEK_SET);
-
-  // Ok let's buffer the first 8 characters to validate "DE_SAVE|"
-  char buffer[SAVE_MANAGER_BUFFER_LENGTH];
-  auto read = fread(buffer, sizeof(char), SAVE_MANAGER_BUFFER_LENGTH, fptr);
-  if(
-    read < 8 ||
-    buffer[0] != 'D' ||
-    buffer[1] != 'E' ||
-    buffer[2] != '_' ||
-    buffer[3] != 'S' ||
-    buffer[4] != 'A' ||
-    buffer[5] != 'V' ||
-    buffer[6] != 'E' ||
-    buffer[7] != '|'
-  ) {
-    fclose(fptr);
-    return SAVE_LOAD_RESULT_CORRUPTED_DE_SAVE;
-  }
-
-  // Now read ahead to the next vertical bar, that will give us the engine
-  // version
-  char *bufferCurrent = buffer + 8;
-  char *p = stringFindNext(bufferCurrent, '|', 10);
-  if(p == NULL) {
-    fclose(fptr);
-    return SAVE_LOAD_RESULT_CORRUPTED_VERSION;
-  }
-  *p = '\0';
-  char *version = bufferCurrent;
-  bufferCurrent = p + 1;
-
-  // Now read the timestamp string.
-  p = stringFindNext(bufferCurrent, '|', 64);
-  if(p == NULL) {
-    fclose(fptr);
-    return SAVE_LOAD_RESULT_CORRUPTED_TIMESTAMP;
-  }
-  *p = '\0';
-  char *strTimestamp = bufferCurrent;
-  
-  // Parse timestamp
-  int64_t timestamp = strtoll(strTimestamp, NULL, 10);
-  if(timestamp == 0) {
-    fclose(fptr);
-    return SAVE_LOAD_RESULT_CORRUPTED_TIMESTAMP;
-  }
-  
-  // Now begin parsing the data in the save file. We start here, at the end of
-  // the previous string, so it will INCLUDE "|" at the first char.
-  read = p - buffer;
-  while(read < (len-1)) {
-    // Rewind and then buffer the next set of bytes
-    fseek(fptr, (long)read, SEEK_SET);
-    if(fread(buffer, sizeof(char), SAVE_MANAGER_BUFFER_LENGTH, fptr) <= 1) {
-      break;
-    }
-
-    // Because we finish the last string INCLUDING "|", then we skip it here.
-    bufferCurrent = buffer + 1;
-
-    // Now, read the key
-    p = stringFindNext(bufferCurrent, '|', SAVE_MANAGER_BUFFER_LENGTH);
-    if(p == NULL) {
-      fclose(fptr);
-      return SAVE_LOAD_RESULT_CORRUPTED_DATA_KEY;
-    }
-
-    *p = '\0';
-    char *key = bufferCurrent;
-
-    // Validate the string lengths
-    if(strlen(key) <= 0) {
-      fclose(fptr);
-      return SAVE_LOAD_RESULT_CORRUPTED_DATA_KEY;
-    }
-
-    // Now read the value
-    bufferCurrent = p + 1;
-    savedata_t destination;
-    uint8_t *ptrValue = (uint8_t*)bufferCurrent;
-    memoryCopy(ptrValue, &destination, sizeof(savedata_t));
-
-    // Now advance the pointer...
-    p = bufferCurrent + sizeof(savedata_t);
-    if(*p != '|') {
-      fclose(fptr);
-      return SAVE_LOAD_RESULT_CORRUPTED_DATA_VALUE;
-    }
-
-    // Set the value.
-    temporaryFile.set(std::string(key), destination);
-    read += (p - buffer);
-  }
-
-  // Close file
-  fclose(fptr);
-
-  // OK Let's validate that everything was read OK
-  if(temporaryFile.get(SAVE_KEY_TIMESTAMP).i64 != timestamp) {
-    return SAVE_LOAD_RESULT_MISMATCH_TIMESTAMP;
-  }
-
-  // Now pass off to the loader
-  if(this->validateSave(temporaryFile) != false) {
-    return SAVE_LOAD_RESULT_ERROR;
-  }
-
-  // Unmark changes. In future I may need to do more complex testing, e.g. if
-  // the game has a newer version that updates save files some how.
-  this->currentSave.hasChanges = false;
-  return SAVE_LOAD_SUCCESS;
-}
-
-void SaveManager::deleteFile(int16_t slot) {
-  assertTrue(slot >= 0);
-}
-
-void SaveManager::useSlot(int16_t slot) {
-  assertTrue(slot >= 0);
-  this->currentSaveSlot = slot;
-  this->currentSave.reset();
-}
-
-std::vector<int16_t> SaveManager::getUsedSlots() {
-  std::vector<int16_t> slots;
-
-  return slots;
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "SaveManager.hpp"
+#include "game/DawnGame.hpp"
+
+using namespace Dawn;
+
+SaveManager::SaveManager(DawnGame *game) {
+  this->game = game;
+}
+
+void SaveManager::saveFile() {
+  savedata_t value;
+
+  assertTrue(this->currentSaveSlot >= 0);
+  
+  // Update metadata
+  auto timestamp = this->game->timeManager.getTimestamp();
+  value.i64 = timestamp;
+  this->currentSave.set(SAVE_KEY_TIMESTAMP, value);
+  value.i16 = this->currentSaveSlot;
+  this->currentSave.set(SAVE_KEY_SLOT, value);
+
+  // Now open output buffer.
+  char filename[SAVE_MANAGER_FILENAME_LENGTH];
+  sprintf(filename, "savefile_%u.save", this->currentSaveSlot);
+  FILE *fptr = fopen(filename, "wb");
+  if(fptr == NULL) {
+    printf("Error opening %s\n", filename);
+    assertUnreachable();
+    return;
+  }
+
+  // Now begin buffering data. First we start with the common phrase, the engine
+  // version, the timestamp. In future we will store the MD5 here too.
+  char buffer[SAVE_MANAGER_BUFFER_LENGTH];
+  auto len = sprintf(buffer, "DE_SAVE|%s|%lld|", "1.00", timestamp);
+  fwrite(buffer, sizeof(char), len, fptr);
+
+  // Now buffer out the data, this is almost certain to change over time.
+  auto it = this->currentSave.values.begin();
+  while(it != this->currentSave.values.end()) {
+    uint8_t *buffer = (uint8_t *)&it->second;
+    char delim = '|';
+    fwrite(it->first.c_str(), sizeof(char), strlen(it->first.c_str()), fptr);
+    fwrite(&delim, sizeof(char), 1, fptr);
+    fwrite(buffer, sizeof(uint8_t), sizeof(savedata_t) / sizeof(uint8_t), fptr);
+    fwrite(&delim, sizeof(char), 1, fptr);
+    ++it;
+  }
+
+  // Buffering done, close the file buffer.
+  fclose(fptr);
+  this->currentSave.hasChanges = false;
+}
+
+enum SaveLoadResult SaveManager::loadFile() {
+  this->currentSave.reset();
+
+  assertTrue(this->currentSaveSlot >= 0);
+
+  // Load file
+  struct SaveFile temporaryFile;
+
+  char filename[SAVE_MANAGER_FILENAME_LENGTH];
+  sprintf(filename, "savefile_%u.save", this->currentSaveSlot);
+  FILE *fptr = fopen(filename, "rb");
+  if(fptr == NULL) {
+    return SAVE_LOAD_RESULT_FILE_NOT_PRESENT;
+  }
+
+  // Let's read how long the file is first.
+  fseek(fptr, 0, SEEK_END);
+  auto len = ftell(fptr);
+
+  // Now let's just ensure the file isn't too small, this starts by us making
+  // sure we have at least "DE_SAVE|%s|%lld|", the string is unknown length, 
+  // but we can be 100% sure of the rest of the file size. So we take
+  // 7+1+1+1+19+1=30
+  if(len < 30) {
+    fclose(fptr);
+    return SAVE_LOAD_RESULT_TOO_SMALL;
+  }
+  
+  // Rewind.
+  fseek(fptr, 0, SEEK_SET);
+
+  // Ok let's buffer the first 8 characters to validate "DE_SAVE|"
+  char buffer[SAVE_MANAGER_BUFFER_LENGTH];
+  auto read = fread(buffer, sizeof(char), SAVE_MANAGER_BUFFER_LENGTH, fptr);
+  if(
+    read < 8 ||
+    buffer[0] != 'D' ||
+    buffer[1] != 'E' ||
+    buffer[2] != '_' ||
+    buffer[3] != 'S' ||
+    buffer[4] != 'A' ||
+    buffer[5] != 'V' ||
+    buffer[6] != 'E' ||
+    buffer[7] != '|'
+  ) {
+    fclose(fptr);
+    return SAVE_LOAD_RESULT_CORRUPTED_DE_SAVE;
+  }
+
+  // Now read ahead to the next vertical bar, that will give us the engine
+  // version
+  char *bufferCurrent = buffer + 8;
+  char *p = stringFindNext(bufferCurrent, '|', 10);
+  if(p == NULL) {
+    fclose(fptr);
+    return SAVE_LOAD_RESULT_CORRUPTED_VERSION;
+  }
+  *p = '\0';
+  char *version = bufferCurrent;
+  bufferCurrent = p + 1;
+
+  // Now read the timestamp string.
+  p = stringFindNext(bufferCurrent, '|', 64);
+  if(p == NULL) {
+    fclose(fptr);
+    return SAVE_LOAD_RESULT_CORRUPTED_TIMESTAMP;
+  }
+  *p = '\0';
+  char *strTimestamp = bufferCurrent;
+  
+  // Parse timestamp
+  int64_t timestamp = strtoll(strTimestamp, NULL, 10);
+  if(timestamp == 0) {
+    fclose(fptr);
+    return SAVE_LOAD_RESULT_CORRUPTED_TIMESTAMP;
+  }
+  
+  // Now begin parsing the data in the save file. We start here, at the end of
+  // the previous string, so it will INCLUDE "|" at the first char.
+  read = p - buffer;
+  while(read < (len-1)) {
+    // Rewind and then buffer the next set of bytes
+    fseek(fptr, (long)read, SEEK_SET);
+    if(fread(buffer, sizeof(char), SAVE_MANAGER_BUFFER_LENGTH, fptr) <= 1) {
+      break;
+    }
+
+    // Because we finish the last string INCLUDING "|", then we skip it here.
+    bufferCurrent = buffer + 1;
+
+    // Now, read the key
+    p = stringFindNext(bufferCurrent, '|', SAVE_MANAGER_BUFFER_LENGTH);
+    if(p == NULL) {
+      fclose(fptr);
+      return SAVE_LOAD_RESULT_CORRUPTED_DATA_KEY;
+    }
+
+    *p = '\0';
+    char *key = bufferCurrent;
+
+    // Validate the string lengths
+    if(strlen(key) <= 0) {
+      fclose(fptr);
+      return SAVE_LOAD_RESULT_CORRUPTED_DATA_KEY;
+    }
+
+    // Now read the value
+    bufferCurrent = p + 1;
+    savedata_t destination;
+    uint8_t *ptrValue = (uint8_t*)bufferCurrent;
+    memoryCopy(ptrValue, &destination, sizeof(savedata_t));
+
+    // Now advance the pointer...
+    p = bufferCurrent + sizeof(savedata_t);
+    if(*p != '|') {
+      fclose(fptr);
+      return SAVE_LOAD_RESULT_CORRUPTED_DATA_VALUE;
+    }
+
+    // Set the value.
+    temporaryFile.set(std::string(key), destination);
+    read += (p - buffer);
+  }
+
+  // Close file
+  fclose(fptr);
+
+  // OK Let's validate that everything was read OK
+  if(temporaryFile.get(SAVE_KEY_TIMESTAMP).i64 != timestamp) {
+    return SAVE_LOAD_RESULT_MISMATCH_TIMESTAMP;
+  }
+
+  // Now pass off to the loader
+  if(saveValidateFile(temporaryFile) != false) {
+    return SAVE_LOAD_RESULT_ERROR;
+  }
+
+  // Unmark changes. In future I may need to do more complex testing, e.g. if
+  // the game has a newer version that updates save files some how.
+  this->currentSave.hasChanges = false;
+  return SAVE_LOAD_SUCCESS;
+}
+
+void SaveManager::deleteFile(int16_t slot) {
+  assertTrue(slot >= 0);
+}
+
+void SaveManager::useSlot(int16_t slot) {
+  assertTrue(slot >= 0);
+  this->currentSaveSlot = slot;
+  this->currentSave.reset();
+}
+
+std::vector<int16_t> SaveManager::getUsedSlots() {
+  std::vector<int16_t> slots;
+
+  return slots;
 }
\ No newline at end of file
diff --git a/src/dawn/save/SaveManager.hpp b/src/dawn/save/SaveManager.hpp
index 120f3ed6..b7507d11 100644
--- a/src/dawn/save/SaveManager.hpp
+++ b/src/dawn/save/SaveManager.hpp
@@ -1,91 +1,91 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "SaveFile.hpp"
-#include "util/string.hpp"
-
-#define SAVE_KEY_TIMESTAMP "meta.timestamp"
-#define SAVE_KEY_SLOT "meta.slot"
-#define SAVE_MANAGER_BUFFER_LENGTH 128
-#define SAVE_MANAGER_FILENAME_LENGTH 512
-
-namespace Dawn {
-  class DawnGame;
-
-  enum SaveLoadResult {
-    SAVE_LOAD_SUCCESS,
-    SAVE_LOAD_RESULT_FILE_NOT_PRESENT,
-    SAVE_LOAD_RESULT_TOO_SMALL,
-    SAVE_LOAD_RESULT_CORRUPTED_DE_SAVE,
-    SAVE_LOAD_RESULT_CORRUPTED_VERSION,
-    SAVE_LOAD_RESULT_CORRUPTED_TIMESTAMP,
-    SAVE_LOAD_RESULT_CORRUPTED_DATA_KEY,
-    SAVE_LOAD_RESULT_CORRUPTED_DATA_VALUE,
-    SAVE_LOAD_RESULT_MISMATCH_TIMESTAMP,
-    SAVE_LOAD_RESULT_ERROR
-  };
-
-  class SaveManager {
-    protected:
-      int16_t currentSaveSlot = -1;
-      struct SaveFile currentSave;
-
-      /**
-       * Reads a save file and then validates all of the values. If a value is 
-       * not validated then it will NOT be retained.
-       * 
-       * @param file Save file to read from.
-       * @return Whether or not the save file is corrupt, false for not corrupt.
-       */
-      virtual bool_t validateSave(struct SaveFile raw) = 0;
-
-    public:
-      DawnGame *game;
-
-      /**
-       * Create a new Save Manager. Used by the game instance to decide when/how
-       * to perform saving.
-       * 
-       * @param game Game that this save manager belongs to.
-       */
-      SaveManager(DawnGame *game);
-
-      /**
-       * Immediately save the game to the given file. This will invoke the 
-       * game's custom writer to write the output data to the save file.
-       */
-      void saveFile();
-
-      /**
-       * Loads the current slotted save file. Invokes the internal managers read
-       * function.
-       */
-      enum SaveLoadResult loadFile();
-
-      /**
-       * Deletes the given save file slot. We use slots here because we need to
-       * be able to delete a file without reading it (in case of corruption).
-       * 
-       * @param slot Slot to delete.
-       */
-      void deleteFile(int16_t slot);
-
-      /**
-       * Determines which save slot to use.
-       * 
-       * @param slot Save slot to use.
-       */
-      void useSlot(int16_t slot);
-
-      /**
-       * Returns a list of used save slots, does not confirm if they are corrupt
-       * or not, just whether they are in existance or not.
-       * 
-       * @return List of used save slots.
-       */
-      std::vector<int16_t> getUsedSlots();
-  };
+// Copyright (c) 2022 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "SaveFile.hpp"
+#include "util/string.hpp"
+
+#define SAVE_KEY_TIMESTAMP "meta.timestamp"
+#define SAVE_KEY_SLOT "meta.slot"
+#define SAVE_MANAGER_BUFFER_LENGTH 128
+#define SAVE_MANAGER_FILENAME_LENGTH 512
+
+namespace Dawn {
+  class DawnGame;
+
+  enum SaveLoadResult {
+    SAVE_LOAD_SUCCESS,
+    SAVE_LOAD_RESULT_FILE_NOT_PRESENT,
+    SAVE_LOAD_RESULT_TOO_SMALL,
+    SAVE_LOAD_RESULT_CORRUPTED_DE_SAVE,
+    SAVE_LOAD_RESULT_CORRUPTED_VERSION,
+    SAVE_LOAD_RESULT_CORRUPTED_TIMESTAMP,
+    SAVE_LOAD_RESULT_CORRUPTED_DATA_KEY,
+    SAVE_LOAD_RESULT_CORRUPTED_DATA_VALUE,
+    SAVE_LOAD_RESULT_MISMATCH_TIMESTAMP,
+    SAVE_LOAD_RESULT_ERROR
+  };
+
+  /**
+   * Reads a save file and then validates all of the values. If a value is 
+   * not validated then it will NOT be retained.
+   * 
+   * @param file Save file to read from.
+   * @return Whether or not the save file is corrupt, false for not corrupt.
+   */
+  bool_t saveValidateFile(struct SaveFile raw);
+
+  class SaveManager {
+    protected:
+      int16_t currentSaveSlot = -1;
+      struct SaveFile currentSave;
+
+    public:
+      DawnGame *game;
+
+      /**
+       * Create a new Save Manager. Used by the game instance to decide when/how
+       * to perform saving.
+       * 
+       * @param game Game that this save manager belongs to.
+       */
+      SaveManager(DawnGame *game);
+
+      /**
+       * Immediately save the game to the given file. This will invoke the 
+       * game's custom writer to write the output data to the save file.
+       */
+      void saveFile();
+
+      /**
+       * Loads the current slotted save file. Invokes the internal managers read
+       * function.
+       */
+      enum SaveLoadResult loadFile();
+
+      /**
+       * Deletes the given save file slot. We use slots here because we need to
+       * be able to delete a file without reading it (in case of corruption).
+       * 
+       * @param slot Slot to delete.
+       */
+      void deleteFile(int16_t slot);
+
+      /**
+       * Determines which save slot to use.
+       * 
+       * @param slot Save slot to use.
+       */
+      void useSlot(int16_t slot);
+
+      /**
+       * Returns a list of used save slots, does not confirm if they are corrupt
+       * or not, just whether they are in existance or not.
+       * 
+       * @return List of used save slots.
+       */
+      std::vector<int16_t> getUsedSlots();
+  };
 }
\ No newline at end of file
diff --git a/src/dawn/scene/CMakeLists.txt b/src/dawn/scene/CMakeLists.txt
index eb4d3d92..1c943bb4 100644
--- a/src/dawn/scene/CMakeLists.txt
+++ b/src/dawn/scene/CMakeLists.txt
@@ -9,7 +9,6 @@ target_sources(${DAWN_TARGET_NAME}
     Scene.cpp
     SceneItem.cpp
     SceneItemComponent.cpp
-    SceneItemComponentList.cpp
 )
 
 # Subdirs
diff --git a/src/dawn/scene/SceneItemComponentList.hpp b/src/dawn/scene/SceneItemComponentList.hpp
deleted file mode 100644
index 20365131..00000000
--- a/src/dawn/scene/SceneItemComponentList.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "dawnlibs.hpp"
-
-namespace Dawn {
-  struct SceneItemComponentRegister {
-    uint8_t i;
-  };
-
-  class SceneItemComponentList {
-    private:
-      std::vector<struct SceneItemComponentRegister> components;
-
-    protected:
-      /**
-       * Request the list to append a scene item component of type T
-       * to the registry.
-       * 
-       * @tparam T Parameter type of the SceneItemComponent
-       */
-      template<class T>
-      void append() {
-        struct SceneItemComponentRegister r;
-        this->components.push_back(r);
-      }
-
-    public:
-      /**
-       * Initialies the scene item component list. This constructor is generated
-       * at build time from the scene item component registry tool.
-       */
-      SceneItemComponentList();
-  };
-}
\ No newline at end of file
diff --git a/src/dawnhelloworld/CMakeLists.txt b/src/dawnhelloworld/CMakeLists.txt
index 71900d88..8de667f3 100644
--- a/src/dawnhelloworld/CMakeLists.txt
+++ b/src/dawnhelloworld/CMakeLists.txt
@@ -14,7 +14,4 @@ target_include_directories(${DAWN_TARGET_NAME}
 
 # Subdirs
 add_subdirectory(game)
-add_subdirectory(save)
-
-# Assets
-tool_bitmapfont(testbitmap bmfont.png 16 16)
\ No newline at end of file
+add_subdirectory(save)
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/CMakeLists.txt b/src/dawnhelloworld/game/CMakeLists.txt
index 8ca94ca8..d7f15aab 100644
--- a/src/dawnhelloworld/game/CMakeLists.txt
+++ b/src/dawnhelloworld/game/CMakeLists.txt
@@ -6,5 +6,5 @@
 # Sources
 target_sources(${DAWN_TARGET_NAME}
   PRIVATE
-    DawnGame.cpp
+    HelloGame.cpp
 )
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/DawnGame.hpp b/src/dawnhelloworld/game/DawnGame.hpp
deleted file mode 100644
index eb00eced..00000000
--- a/src/dawnhelloworld/game/DawnGame.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "game/_DawnGame.hpp"
-#include "save/DawnGameSaveManager.hpp"
-
-namespace Dawn {
-  class DawnGame : public IDawnGame {
-    private:
-      Scene *sceneToCutTo = nullptr;
-      
-    public:
-      DawnHost *host;
-      RenderManager renderManager;
-      AssetManager assetManager;
-      InputManager inputManager;
-      TimeManager timeManager;
-      DawnGameSaveManager saveManager;
-      
-      DawnGame(DawnHost *host);
-      int32_t init() override;
-      int32_t update(float_t delta) override;
-      void sceneCutover(Scene *scene) override;
-  };
-}
\ No newline at end of file
diff --git a/src/dawnhelloworld/game/HelloGame.cpp b/src/dawnhelloworld/game/HelloGame.cpp
new file mode 100644
index 00000000..105be5d3
--- /dev/null
+++ b/src/dawnhelloworld/game/HelloGame.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "game/DawnGame.hpp"
+#include "scenes/HelloWorldScene.hpp"
+
+using namespace Dawn;
+
+Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) {
+  return new HelloWorldScene(game);
+}
\ No newline at end of file
diff --git a/src/dawnhelloworld/save/CMakeLists.txt b/src/dawnhelloworld/save/CMakeLists.txt
index 2d057169..4e9e33ce 100644
--- a/src/dawnhelloworld/save/CMakeLists.txt
+++ b/src/dawnhelloworld/save/CMakeLists.txt
@@ -6,5 +6,5 @@
 # Sources
 target_sources(${DAWN_TARGET_NAME}
   PRIVATE
-    DawnGameSaveManager.cpp
+    HelloSave.cpp
 )
\ No newline at end of file
diff --git a/src/dawnhelloworld/save/DawnGameSaveManager.cpp b/src/dawnhelloworld/save/DawnGameSaveManager.cpp
deleted file mode 100644
index 75a006b4..00000000
--- a/src/dawnhelloworld/save/DawnGameSaveManager.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "DawnGameSaveManager.hpp"
-
-using namespace Dawn;
-
-DawnGameSaveManager::DawnGameSaveManager(DawnGame *game) : SaveManager(game) {
-}
-
-bool_t DawnGameSaveManager::validateSave(struct SaveFile raw) {
-  if(!raw.has(POKER_SAVE_KEY_EXAMPLE)) return true;
-  this->currentSave.copy(raw, POKER_SAVE_KEY_EXAMPLE);
-
-  return false;
-}
-
-void DawnGameSaveManager::setExample(int32_t val) {
-  savedata_t value;
-  value.i32 = val;
-  this->currentSave.set(POKER_SAVE_KEY_EXAMPLE, value);
-}
-
-int32_t DawnGameSaveManager::getExample() {
-  return this->currentSave.get(POKER_SAVE_KEY_EXAMPLE).i32;
-}
\ No newline at end of file
diff --git a/src/dawnhelloworld/save/DawnGameSaveManager.hpp b/src/dawnhelloworld/save/DawnGameSaveManager.hpp
deleted file mode 100644
index bc946262..00000000
--- a/src/dawnhelloworld/save/DawnGameSaveManager.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2023 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "save/SaveManager.hpp"
-
-#define POKER_SAVE_KEY_EXAMPLE "poker.example"
-
-namespace Dawn {
-  class DawnGameSaveManager : public SaveManager {
-    protected:
-      virtual bool_t validateSave(struct SaveFile raw) override;
-
-    public:
-      DawnGameSaveManager(DawnGame *game);
-
-      void setExample(int32_t value);
-      int32_t getExample();
-  };
-}
\ No newline at end of file
diff --git a/src/dawn/scene/SceneItemComponentList.cpp b/src/dawnhelloworld/save/HelloSave.cpp
similarity index 51%
rename from src/dawn/scene/SceneItemComponentList.cpp
rename to src/dawnhelloworld/save/HelloSave.cpp
index a16663bf..3c029bd4 100644
--- a/src/dawn/scene/SceneItemComponentList.cpp
+++ b/src/dawnhelloworld/save/HelloSave.cpp
@@ -3,6 +3,10 @@
 // This software is released under the MIT License.
 // https://opensource.org/licenses/MIT
 
-#include "SceneItemComponentList.hpp"
+#include "save/SaveManager.hpp"
 
-using namespace Dawn;
\ No newline at end of file
+using namespace Dawn;
+
+bool_t Dawn::saveValidateFile(struct SaveFile raw) {
+  return false;
+}
\ No newline at end of file
diff --git a/src/dawnosui/display/CMakeLists.txt b/src/dawnosui/display/CMakeLists.txt
deleted file mode 100644
index 97421ebe..00000000
--- a/src/dawnosui/display/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Subdirs
-add_subdirectory(shader)
\ No newline at end of file
diff --git a/src/dawnosui/display/shader/CMakeLists.txt b/src/dawnosui/display/shader/CMakeLists.txt
deleted file mode 100644
index f314bd49..00000000
--- a/src/dawnosui/display/shader/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Sources
\ No newline at end of file
diff --git a/src/dawnosui/display/shader/TestBackgroundShader.hpp b/src/dawnosui/display/shader/TestBackgroundShader.hpp
deleted file mode 100644
index 0097b4ca..00000000
--- a/src/dawnosui/display/shader/TestBackgroundShader.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "display/shader/Shader.hpp"
-#include "scene/components/Components.hpp"
-
-namespace Dawn {
-  class TestBackgroundShader : public Shader {
-    public:
-      shaderparameter_t paramProjection;
-      shaderparameter_t paramView;
-      shaderparameter_t paramTime;
-
-      std::map<shaderparameter_t, enum ShaderParameterType>
-      getParameters() override {
-        std::map<shaderparameter_t, enum ShaderParameterType> ps;
-        ps[paramTime] = SHADER_PARAMETER_TYPE_FLOAT;
-        return ps;
-      }
-      
-      void setDefaultParameters(Material &material) override {
-        material.floatValues[this->paramTime] = 0.0f;
-      }
-
-      void setGlobalParameters(glm::mat4 proj, glm::mat4 view) override {
-        this->setMatrix(this->paramProjection, proj);
-        this->setMatrix(this->paramView, view);
-      }
-
-      void setMeshParameters(glm::mat4 transform) override {}
-
-      void bindTexture(
-        shaderparameter_t param,
-        Texture *texture
-      ) override {}
-
-      void compile() override {
-        this->compileShader(R"GLSL(
-            #version 330 core
-            layout (location = 0) in vec3 aPos;
-            layout (location = 1) in vec2 aTexCoord;
-
-            uniform mat4 u_Proj;
-            uniform mat4 u_View;
-
-            out vec2 o_TextCoord;
-            void main() {
-              gl_Position = u_Proj * u_View * vec4(aPos, 1.0);
-              o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);
-            }
-          )GLSL", R"GLSL(
-            #version 330 core
-            out vec4 o_Color;
-            in vec2 o_TextCoord;
-            uniform float u_Time;
-
-            void main() {
-              highp float tSpan = 4.0;
-              highp float halfTSpan = tSpan / 2.0;
-              highp float t = mod(u_Time, tSpan);
-              if(t > halfTSpan) {
-                t = halfTSpan + (halfTSpan - t);
-              }
-              t = t / halfTSpan;
-
-              highp float x = o_TextCoord.x;
-              highp float y = o_TextCoord.y;
-              float h = sin(x + u_Time) / 4 + 0.5;
-
-              highp float r = (0.6 + ((y * t) / 5.0));
-              highp float g = 0.4 + ((x * t) / (10 + (t * 3)));
-              highp float b = 0.8 + ((0.2 * t) - (x / 5));
-              highp float global = 0.7 + ((0.1 + (y * 0.6)) / h / 4.0);
-
-              
-              o_Color = vec4(
-                r * global,
-                g * global,
-                b * global,
-                1.0
-              );
-            }
-          )GLSL"
-        );
-
-        this->paramProjection = this->getParameterByName("u_Proj");
-        this->paramView = this->getParameterByName("u_View");
-        this->paramTime = this->getParameterByName("u_Time");
-      }
-  };
-}
\ No newline at end of file
diff --git a/src/dawnosui/game/DawnPokerGame.cpp b/src/dawnosui/game/DawnPokerGame.cpp
deleted file mode 100644
index 6618cb65..00000000
--- a/src/dawnosui/game/DawnPokerGame.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#include "DawnPokerGame.hpp"
-
-using namespace Dawn;
-
-std::shared_ptr<Material> material;
-std::shared_ptr<TestBackgroundShader> shader;
-
-DawnGame::DawnGame(DawnHost &host) :
-  host(host),
-  renderManager(*this),
-  inputManager(*this)
-{
-}
-
-int32_t DawnGame::init() {
-  this->assetManager.init();
-  this->renderManager.init();
-
-  this->scene = std::make_shared<Scene>(*this);
-
-  auto cameraObject = this->scene->createSceneItem();
-  auto camera = cameraObject->addComponent<Camera>();
-  camera->type = CAMERA_TYPE_ORTHONOGRAPHIC;
-  camera->orthoLeft = 0.0f;
-  camera->orthoRight = 1.0f;
-  camera->orthoTop = 0.0f;
-  camera->orthoBottom = 1.0f;
-  camera->transform.lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0));
-  // camera->transform.lookAt(glm::vec3(50, 50, 50), glm::vec3(0, 0, 0));
-
-  auto quad = this->scene->createSceneItem();
-  auto meshRenderer = quad->addComponent<MeshRenderer>();
-  meshRenderer->mesh = std::make_shared<Mesh>();
-  meshRenderer->mesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
-  QuadMesh::bufferQuadMesh(meshRenderer->mesh.get(),
-    glm::vec2(0, 0), glm::vec2(0, 0),
-    glm::vec2(1.0f, 1.0f), glm::vec2(1.0f, 1.0f),
-    0, 0
-  );
-
-  shader = std::make_shared<TestBackgroundShader>();
-  shader->compile();
-  material = quad->addComponent<Material>();
-  material->setShader(shader);
-  
-  return DAWN_GAME_INIT_RESULT_SUCCESS;
-}
-
-int32_t DawnGame::update(float_t delta) {
-  this->assetManager.update();
-  this->inputManager.update();
-  this->timeManager.update(delta);
-
-  if(this->scene != nullptr) this->scene->update();
-
-  material->floatValues[shader->paramTime] = this->timeManager.time;
-  
-  this->renderManager.update();
-  return DAWN_GAME_UPDATE_RESULT_SUCCESS;
-}
-
-DawnGame::~DawnGame() {
-  
-}
\ No newline at end of file
diff --git a/src/dawnosui/game/DawnPokerGame.hpp b/src/dawnosui/game/DawnPokerGame.hpp
deleted file mode 100644
index d73532d8..00000000
--- a/src/dawnosui/game/DawnPokerGame.hpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "game/DawnGame.hpp"
-#include "scene/components/Components.hpp"
-#include "display/mesh/QuadMesh.hpp"
-#include "display/shader/TestBackgroundShader.hpp"
\ No newline at end of file
diff --git a/src/dawnosui/input/InputBinds.hpp b/src/dawnosui/input/InputBinds.hpp
deleted file mode 100644
index 9e400ad8..00000000
--- a/src/dawnosui/input/InputBinds.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2022 Dominic Masters
-// 
-// This software is released under the MIT License.
-// https://opensource.org/licenses/MIT
-
-#pragma once
-#include "input/InputManager.hpp"
-
-#define INPUT_BIND_ACCEPT ((inputbind_t)1)
\ No newline at end of file
diff --git a/src/dawnosui/CMakeLists.txt b/src/dawnrose/CMakeLists.txt
similarity index 64%
rename from src/dawnosui/CMakeLists.txt
rename to src/dawnrose/CMakeLists.txt
index 86f85f3d..8de667f3 100644
--- a/src/dawnosui/CMakeLists.txt
+++ b/src/dawnrose/CMakeLists.txt
@@ -1,20 +1,17 @@
-# Copyright (c) 2022 Dominic Masters
-# 
-# This software is released under the MIT License.
-# https://opensource.org/licenses/MIT
-
-# Set up the executable
-set(DAWN_TARGET_NAME "DawnOS" CACHE INTERNAL ${DAWN_CACHE_TARGET})
-
-# Build Project
-add_executable(${DAWN_TARGET_NAME})
-
-# Includes
-target_include_directories(${DAWN_TARGET_NAME}
-  PUBLIC
-    ${CMAKE_CURRENT_LIST_DIR}
-)
-
-# Subdirs
-add_subdirectory(game)
-add_subdirectory(display)
\ No newline at end of file
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Build Project
+add_executable(${DAWN_TARGET_NAME})
+
+# Includes
+target_include_directories(${DAWN_TARGET_NAME}
+  PUBLIC
+    ${CMAKE_CURRENT_LIST_DIR}
+)
+
+# Subdirs
+add_subdirectory(game)
+add_subdirectory(save)
\ No newline at end of file
diff --git a/src/dawnrose/game/CMakeLists.txt b/src/dawnrose/game/CMakeLists.txt
new file mode 100644
index 00000000..4010ac25
--- /dev/null
+++ b/src/dawnrose/game/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    RoseGame.cpp
+)
\ No newline at end of file
diff --git a/src/dawnrose/game/RoseGame.cpp b/src/dawnrose/game/RoseGame.cpp
new file mode 100644
index 00000000..105be5d3
--- /dev/null
+++ b/src/dawnrose/game/RoseGame.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "game/DawnGame.hpp"
+#include "scenes/HelloWorldScene.hpp"
+
+using namespace Dawn;
+
+Scene * Dawn::dawnGameGetInitialScene(DawnGame *game) {
+  return new HelloWorldScene(game);
+}
\ No newline at end of file
diff --git a/src/dawnrose/input/InputBinds.hpp b/src/dawnrose/input/InputBinds.hpp
new file mode 100644
index 00000000..32fc1016
--- /dev/null
+++ b/src/dawnrose/input/InputBinds.hpp
@@ -0,0 +1,19 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "input/InputManager.hpp"
+
+#define INPUT_BIND(n) ((inputbind_t)n)
+
+#define INPUT_BIND_ACCEPT INPUT_BIND(1)
+#define INPUT_BIND_NEGATIVE_X INPUT_BIND(2)
+#define INPUT_BIND_POSITIVE_X INPUT_BIND(3)
+#define INPUT_BIND_NEGATIVE_Y INPUT_BIND(4)
+#define INPUT_BIND_POSITIVE_Y INPUT_BIND(5)
+#define INPUT_BIND_MOUSE_X INPUT_BIND(6)
+#define INPUT_BIND_MOUSE_Y INPUT_BIND(7)
+#define INPUT_BIND_MOUSE_CLICK INPUT_BIND(8)
+#define INPUT_BIND_CANCEL INPUT_BIND(9)
\ No newline at end of file
diff --git a/src/dawnrose/save/CMakeLists.txt b/src/dawnrose/save/CMakeLists.txt
new file mode 100644
index 00000000..4d899f55
--- /dev/null
+++ b/src/dawnrose/save/CMakeLists.txt
@@ -0,0 +1,10 @@
+# Copyright (c) 2023 Dominic Masters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+target_sources(${DAWN_TARGET_NAME}
+  PRIVATE
+    RoseSave.cpp
+)
\ No newline at end of file
diff --git a/src/dawnrose/save/RoseSave.cpp b/src/dawnrose/save/RoseSave.cpp
new file mode 100644
index 00000000..3c029bd4
--- /dev/null
+++ b/src/dawnrose/save/RoseSave.cpp
@@ -0,0 +1,12 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "save/SaveManager.hpp"
+
+using namespace Dawn;
+
+bool_t Dawn::saveValidateFile(struct SaveFile raw) {
+  return false;
+}
\ No newline at end of file
diff --git a/src/dawnrose/scenes/HelloWorldScene.hpp b/src/dawnrose/scenes/HelloWorldScene.hpp
new file mode 100644
index 00000000..5409cd0d
--- /dev/null
+++ b/src/dawnrose/scenes/HelloWorldScene.hpp
@@ -0,0 +1,65 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "scene/Scene.hpp"
+#include "prefabs/SimpleSpinningCubePrefab.hpp"
+#include "scene/components/ui/UILabel.hpp"
+#include "scene/components/ui/UIImage.hpp"
+#include "display/font/BitmapFont.hpp"
+
+namespace Dawn {
+  class HelloWorldScene : public Scene {
+    protected:
+      Camera *camera;
+      SimpleSpinningCubePrefab *cube;
+      UICanvas *canvas;
+      UILabel *label;
+      UIImage *image;
+      BitmapFont font;
+
+      void stage() override {
+        camera = Camera::create(this);
+        camera->transform->lookAt(glm::vec3(0, 0, 8), glm::vec3(0, 0, 0));
+
+        cube = SimpleSpinningCubePrefab::create(this);
+
+        canvas = UICanvas::create(this);
+
+        auto imageItem = this->createSceneItem();
+        image = imageItem->addComponent<UIImage>();
+        image->color = COLOR_BLACK;
+        imageItem->transform.setParent(canvas->transform);
+
+        auto labelItem = this->createSceneItem();
+        label = labelItem->addComponent<UILabel>();
+        labelItem->transform.setParent(canvas->transform);
+
+        auto assMan = &this->game->assetManager;
+        auto texture = assMan->get<TextureAsset>("testbitmap_texture");
+        auto tileset = assMan->get<TilesetAsset>("testbitmap_tileset");
+        this->font.texture = &texture->texture;
+        this->font.tileset = &tileset->tileset;
+
+        label->text = "Hello World, how are you today? I hope you are doing well. I really like the fact I can ramble in my text for once.";
+        label->font = &font;
+        label->maxWidth = 220;
+
+        image->alignment = glm::vec4(0, 0, label->getContentWidth(), label->getContentHeight());
+      }
+      
+      std::vector<Asset*> getRequiredAssets() override {
+        auto assMan = &this->game->assetManager;
+        std::vector<Asset*> assets;
+        vectorAppend(&assets, SimpleSpinningCubePrefab::getRequiredAssets(assMan));
+        assets.push_back(assMan->get<TextureAsset>("testbitmap_texture"));
+        assets.push_back(assMan->get<TilesetAsset>("testbitmap_tileset"));
+        return assets;
+      }
+
+    public:
+      HelloWorldScene(DawnGame *game) : Scene(game) {}
+  };
+}
\ No newline at end of file