diff --git a/demo/demo/main.cpp b/demo/demo/main.cpp
index 38942cf91710fa58ddc4d688f3a5e7930acdc211..59a6cb0318e003ef496f3f5d80f2ff6ecfbae4b9 100644
--- a/demo/demo/main.cpp
+++ b/demo/demo/main.cpp
@@ -25,6 +25,8 @@
 	#include "fggl/phys/bullet/bullet.hpp"
 #endif
 
+#include "fggl/subsystem/subsystem.hpp"
+
 #include "fggl/app.hpp"
 #include "fggl/audio/openal/audio.hpp"
 
@@ -74,32 +76,28 @@ static void test_atlas_api() {
 	auto *atlas = fggl::gfx::ImageAtlas<char>::pack(images);
 }
 
-static void setup_service_locators(fggl::util::ServiceLocator& locator) {
+int main(int argc, const char* argv[]) {
 	auto pathConfig = fggl::platform::calc_engine_paths("fggl-demo");
 
-	// FIXME: janky API(s)
-	auto inputs = locator.supply<fggl::input::Input>(std::make_shared<fggl::input::Input>());
-	auto storage = locator.supply<fggl::data::Storage>(std::make_shared<fggl::data::Storage>(pathConfig));
+	fggl::subsystem::SubsystemManager manager;
+	manager.provide<fggl::data::Storage>(new fggl::data::Storage(pathConfig));
+	manager.provide<fggl::audio::AudioService>(new fggl::audio::openAL());
 
-	locator.supply<fggl::gui::FontLibrary>(std::make_shared<fggl::gui::FontLibrary>());
-	locator.supply<fggl::ecs3::TypeRegistry>(std::make_shared<fggl::ecs3::TypeRegistry>());
-	locator.supply<fggl::audio::AudioService>(std::make_shared<fggl::audio::openAL>());
-}
-
-int main(int argc, const char* argv[]) {
+	manager.setTypeRegistry(new fggl::ecs3::TypeRegistry());
+	manager.setFontLibrary(new fggl::gui::FontLibrary());
+	manager.setInput(new fggl::input::Input());
 
-	auto& locator = fggl::util::ServiceLocator::instance();
-	setup_service_locators(locator);
+	manager.setup();
 
 	// create the application
-	fggl::App app( "fggl-demo" );
+	fggl::App app( &manager, "fggl-demo" );
 
 	// Would be nice to not take args like this, it messes with lifetimes
-	auto& windowing = app.use<fggl::gfx::ecsGlfwModule>(locator.get<fggl::input::Input>());
+	auto& windowing = app.use<fggl::gfx::ecsGlfwModule>( manager.getInput() );
 
     // -- should not be our problem - this is a broken api
     auto window = windowing.createWindow("Demo Game");
-	window->make_graphics<fggl::gfx::OpenGL4>();
+	window->make_graphics<fggl::gfx::OpenGL4>(manager.getStorage(), manager.getFontLibrary());
     window->fullscreen( true );
     app.setWindow( std::move(window) );
 
@@ -116,7 +114,7 @@ int main(int argc, const char* argv[]) {
     auto *menu = app.add_state<fggl::scenes::BasicMenu>("menu");
 
 	// add some menu items for the game states
-	auto audio = locator.get<fggl::audio::AudioService>();
+	auto* audio = manager.getAudio();
     menu->add("terrain", [&app, &audio]() {
 		audio->play("click.ogg", false);
 		app.change_state("game");
diff --git a/demo/demo/rollball.cpp b/demo/demo/rollball.cpp
index d22a7ba67a80ca18f0e5578eb4fbf82851aaea5f..82713369300c46c8d8761ba50317cade612971d6 100644
--- a/demo/demo/rollball.cpp
+++ b/demo/demo/rollball.cpp
@@ -34,9 +34,7 @@ struct Prefabs {
 	fggl::ecs3::entity_t player;
 };
 
-static void setup_prefabs(fggl::ecs3::World& world, Prefabs& prefabs) {
-
-	auto storage = fggl::util::ServiceLocator::instance().get<fggl::data::Storage>();
+static void setup_prefabs(fggl::data::Storage* storage, fggl::ecs3::World& world, Prefabs& prefabs) {
 	fggl::ecs3::load_prototype_file(world, *storage, "rollball.yml");
 
 	{
@@ -148,7 +146,7 @@ namespace demo {
 		Game::activate();
 
 		Prefabs prefabs{};
-		setup_prefabs(world(), prefabs);
+		setup_prefabs(m_owner.services()->getStorage(), world(), prefabs);
 
 		// collectable callbacks
 		auto* collectableCallbacks = world().get<fggl::phys::CollisionCallbacks>(prefabs.collectable);
diff --git a/fggl/app.cpp b/fggl/app.cpp
index 7d1c223d5159b8c14b7a47e05618fccf2c3195fb..db9fbd32a17454ce0415bbc4db84b01ebc201a3d 100644
--- a/fggl/app.cpp
+++ b/fggl/app.cpp
@@ -24,15 +24,16 @@
 
 namespace fggl {
 
-    App::App(const Identifer& name) : App::App( name, name ) {
+    App::App(subsystem::ServiceProvider* services, const Identifer& name) : App::App( services, name, name ) {
     }
 
-    App::App(const Identifer& name, const Identifer& folder ) :
+    App::App(subsystem::ServiceProvider* services, const Identifer& name, const Identifer& folder ) :
         m_running(true),
         m_types(std::make_unique<ecs3::TypeRegistry>()),
         m_modules(std::make_unique<ecs3::ModuleManager>(*m_types)),
 		m_window(nullptr),
-        m_states() {}
+        m_states(),
+		m_subsystems(services){}
 
     int App::run(int argc, const char** argv) {
 
diff --git a/fggl/audio/openal/audio.cpp b/fggl/audio/openal/audio.cpp
index e7777a9b8af9071192cab7158ff9f01f6fbaf2f9..d79ae610ad53caaf0e2297e6b3e9c926740a04df 100644
--- a/fggl/audio/openal/audio.cpp
+++ b/fggl/audio/openal/audio.cpp
@@ -30,6 +30,7 @@
 
 #include "fggl/util/service.hpp"
 #include "fggl/data/storage.hpp"
+#include "fggl/subsystem/provider.hpp"
 
 namespace fggl::audio::openal {
 
@@ -37,11 +38,10 @@ namespace fggl::audio::openal {
 
 		// load audio clip into temp storage
 		AudioClip clip;
-		auto& locator = util::ServiceLocator::instance();
-		auto storage = locator.get<data::Storage>();
-		bool result = storage->load(data::StorageType::Data, filename, &clip);
+		bool result = m_storage->load(data::StorageType::Data, filename, &clip);
 		if ( !result ) {
 			std::cerr << "error: can't load audio data" << std::endl;
+			return;
 		}
 
 		play(clip, looping);
@@ -53,4 +53,8 @@ namespace fggl::audio::openal {
 			m_defaultSource->play(clip, looping);
 		}
 	}
+
+	void AudioServiceOAL::setup(data::Storage* storage) {
+		m_storage = storage;
+	}
 }
\ No newline at end of file
diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp
index 2ded83f2911ad55b2960842ef2dceb44bd4295aa..564a75478d1096b742c4c37b12f013b90b0215e7 100644
--- a/fggl/gfx/ogl/renderer.cpp
+++ b/fggl/gfx/ogl/renderer.cpp
@@ -135,7 +135,7 @@ namespace fggl::gfx {
 	using data::Mesh2D;
 	using data::Vertex2D;
 
-	OpenGL4Backend::OpenGL4Backend(const Window &owner) : fggl::gfx::Graphics(), m_canvasPipeline(INVALID_SHADER_ID) {
+	OpenGL4Backend::OpenGL4Backend(const Window &owner, data::Storage* storage, gui::FontLibrary* fonts) : fggl::gfx::Graphics(), m_canvasPipeline(INVALID_SHADER_ID), m_storage(storage) {
 		// initialise GLEW, or fail
 		// FIXME this binds the graphics stack to GLFW :'(
 		int version = gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress );
@@ -159,9 +159,7 @@ namespace fggl::gfx {
 		glViewport(0, 0, fbSize.x, fbSize.y);
 
 		// setup the shader cache
-		auto &locator = util::ServiceLocator::instance();
-		auto storage = locator.get<data::Storage>();
-		m_cache = std::make_unique<ShaderCache>(storage);
+		m_cache = std::make_unique<ShaderCache>(m_storage);
 
 		// setup 2D rendering system
 		ShaderConfig shader2DConfig = ShaderFromName("canvas");
@@ -175,7 +173,7 @@ namespace fggl::gfx {
 		m_cache->load(shader3DConfig);
 
 		// rendering helpers
-		m_canvasRenderer = std::make_unique<ogl4::CanvasRenderer>();
+		m_canvasRenderer = std::make_unique<ogl4::CanvasRenderer>(fonts);
 		m_modelRenderer = std::make_unique<ogl4::StaticModelRenderer>(m_cache.get());
 
 		m_debugRenderer = std::make_unique<ogl4::DebugRenderer>(m_cache->getOrLoad(ShaderFromName("debug")));
diff --git a/fggl/gfx/ogl/shader.cpp b/fggl/gfx/ogl/shader.cpp
index dcba3cd1fe1ae898c3cd02f23e964618a5e6f7ac..a38aec9a5cdc4efff38ca1fd2aedd5bd9ade5983 100644
--- a/fggl/gfx/ogl/shader.cpp
+++ b/fggl/gfx/ogl/shader.cpp
@@ -57,7 +57,7 @@ bool ShaderCache::readAndCompileShader(const std::string &filename, GLuint shade
 	return compileShaderFromSource(source, shader);
 }
 
-ShaderCache::ShaderCache(std::shared_ptr<fggl::data::Storage> storage) : m_storage(storage), m_shaders(), m_binary(true) {
+ShaderCache::ShaderCache(fggl::data::Storage* storage) : m_storage(storage), m_shaders(), m_binary(true) {
 
 	if ( !GLAD_GL_ARB_get_program_binary ) {
 		spdlog::warn("the graphics card doesn support shader caching, disabling");
diff --git a/fggl/gfx/ogl4/canvas.cpp b/fggl/gfx/ogl4/canvas.cpp
index 189a0d8fd89a753ddb388d8d9da391c2dd485056..59f1babeba7137c880b2bb499140e2c5c1f64d7a 100644
--- a/fggl/gfx/ogl4/canvas.cpp
+++ b/fggl/gfx/ogl4/canvas.cpp
@@ -85,8 +85,9 @@ namespace fggl::gfx::ogl4 {
 		}
 	}
 
-	CanvasRenderer::CanvasRenderer() :
+	CanvasRenderer::CanvasRenderer(fggl::gui::FontLibrary* fonts) :
 		m_bounds({0.0F, 1920.F, 1080.0F, 0.0F}),
+		m_fonts(fonts),
 		m_fontTex(ogl::TextureType::Tex2D) {
 		m_vao.bind();
 
@@ -151,8 +152,7 @@ namespace fggl::gfx::ogl4 {
 
 
 		// get the expected font
-		auto fontFactory = util::ServiceLocator::instance().get<gui::FontLibrary>();
-		std::shared_ptr<gui::FontFace> face = fontFactory->getFont("LiberationSans-Regular.ttf");
+		std::shared_ptr<gui::FontFace> face = m_fonts->getFont("LiberationSans-Regular.ttf");
 		if ( face == nullptr ){
 			// we don't know about that font...
 			return;
diff --git a/fggl/gfx/window.cpp b/fggl/gfx/window.cpp
index 379e55561a997f502d78e67e5a685ced0dea4419..1a7a117243afe4f68fb0082251d5e5d4e27efd97 100644
--- a/fggl/gfx/window.cpp
+++ b/fggl/gfx/window.cpp
@@ -122,10 +122,10 @@ static void fggl_joystick(int jid, int state) {
 	}
 }
 
-GlfwContext::GlfwContext( std::shared_ptr<fggl::input::Input> input ) {
+GlfwContext::GlfwContext( fggl::input::Input* input ) {
     spdlog::debug("[glfw] context creation stated");
 	auto& glfwCallbacks = GlfwInputManager::instance();
-	glfwCallbacks.setup( std::move(input) );
+	glfwCallbacks.setup( input );
 
 	glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE);
     glfwSetErrorCallback(glfw_error);
diff --git a/fggl/scenes/game.cpp b/fggl/scenes/game.cpp
index 6059ad5f319932a39ec05b76331a9f0c3c4e35cc..8f749c93f273409a380671062eb7735affde7f4b 100644
--- a/fggl/scenes/game.cpp
+++ b/fggl/scenes/game.cpp
@@ -26,8 +26,7 @@
 namespace fggl::scenes {
 
 	Game::Game(fggl::App &app) : AppState(app) {
-		auto& locator = fggl::util::ServiceLocator::instance();
-		m_input = locator.get<fggl::input::Input>();
+		m_input = app.services()->getInput();
 	}
 
 	void Game::activate() {
diff --git a/fggl/scenes/menu.cpp b/fggl/scenes/menu.cpp
index 5f90ba21554988b47e3ee653e4d188470ad16ba0..36e2ec76c5a7a30ad8310a47ed8bae160c7a3de8 100644
--- a/fggl/scenes/menu.cpp
+++ b/fggl/scenes/menu.cpp
@@ -26,8 +26,7 @@ namespace fggl::scenes {
 
 
     BasicMenu::BasicMenu(fggl::App& app) : AppState(app), m_inputs(nullptr), m_active(), m_hover(nullptr) {
-        auto& locator = fggl::util::ServiceLocator::instance();
-        m_inputs = locator.get<input::Input>();
+        m_inputs = app.services()->getInput();
     }
 
     void BasicMenu::update() {
diff --git a/include/fggl/app.hpp b/include/fggl/app.hpp
index cca6961536530ccb38f8d608f5711ca5e9fbd182..5a63c0a4b634c6b9490d019c8d7528981b5a1faf 100644
--- a/include/fggl/app.hpp
+++ b/include/fggl/app.hpp
@@ -27,6 +27,7 @@
 #include <fggl/gfx/window.hpp>
 #include <fggl/gfx/paint.hpp>
 #include <fggl/util/states.hpp>
+#include "fggl/subsystem/provider.hpp"
 
 namespace fggl {
 
@@ -82,8 +83,8 @@ namespace fggl {
 
 	class App {
 		public:
-			explicit App(const Identifer &name);
-			App(const Identifer &name, const Identifer &folderName);
+			explicit App(subsystem::ServiceProvider* serivces, const Identifer &name);
+			App(subsystem::ServiceProvider* services, const Identifer &name, const Identifer &folderName);
 
 			// class is non copy-able
 			App(const App &app) = delete;
@@ -124,6 +125,10 @@ namespace fggl {
 				return m_states.active();
 			}
 
+			inline subsystem::ServiceProvider* services() {
+				return m_subsystems;
+			}
+
 			inline ecs3::TypeRegistry* registry() {
 				return m_types.get();
 			}
@@ -143,6 +148,7 @@ namespace fggl {
 			std::unique_ptr<gfx::Window> m_window;
 			AppMachine m_states;
 			Identifer m_expectedScene;
+			subsystem::ServiceProvider* m_subsystems;
 	};
 
 }
diff --git a/include/fggl/audio/audio.hpp b/include/fggl/audio/audio.hpp
index 3e91b653c245e2739bdd4702949e3abc47545276..e1d16516001bc721283f315145e466a3e0f43eed 100644
--- a/include/fggl/audio/audio.hpp
+++ b/include/fggl/audio/audio.hpp
@@ -16,6 +16,8 @@
 #define FGGL_AUDIO_AUDIO_HPP
 
 #include <string>
+#include "fggl/subsystem/types.hpp"
+#include "fggl/data/storage.hpp"
 
 namespace fggl::audio {
 
@@ -36,6 +38,8 @@ namespace fggl::audio {
 			AudioService() = default;
 			virtual ~AudioService() = default;
 
+			virtual void setup(data::Storage* provider) = 0;
+
 			virtual void play(const std::string& filename, bool looping = false) = 0;
 			virtual void play(AudioClip& clip, bool looping = false) = 0;
 	};
diff --git a/include/fggl/audio/null_audio.hpp b/include/fggl/audio/null_audio.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ccefb33e5530ce25c75fc25e9b8bde6ab6552b8d
--- /dev/null
+++ b/include/fggl/audio/null_audio.hpp
@@ -0,0 +1,38 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 27/06/22.
+//
+
+#ifndef FGGL_AUDIO_NULL_AUDIO_HPP
+#define FGGL_AUDIO_NULL_AUDIO_HPP
+
+#include "fggl/audio/audio.hpp"
+
+namespace fggl::audio {
+
+	class NullAudioService : public AudioService {
+		public:
+			NullAudioService() = default;
+			virtual ~NullAudioService() = default;
+
+			void setup(data::Storage* storage) override {}
+			void play(const std::string& filename, bool looping = false) override {}
+			void play(AudioClip& clip, bool looping = false) override {}
+	};
+
+} // namespace fggl::audio
+
+#endif //FGGL_AUDIO_NULL_AUDIO_HPP
diff --git a/include/fggl/audio/openal/audio.hpp b/include/fggl/audio/openal/audio.hpp
index ec17ab140b6015bf5b3a52de196a9a326910bd66..88e59d0936da54f96d6d971ffc1e6e749af0f1db 100644
--- a/include/fggl/audio/openal/audio.hpp
+++ b/include/fggl/audio/openal/audio.hpp
@@ -23,6 +23,7 @@
 #include <AL/alc.h>
 
 #include "fggl/audio/audio.hpp"
+#include "fggl/data/storage.hpp"
 #include "fggl/math/types.hpp"
 
 #include <string>
@@ -171,6 +172,7 @@ namespace fggl::audio::openal {
 				}
 			}
 
+			void setup(data::Storage* storage) override;
 			void play(const std::string& filename, bool looping = false) override;
 			void play(AudioClip& clip, bool looping = false) override;
 
@@ -178,6 +180,7 @@ namespace fggl::audio::openal {
 			ALCdevice* m_device;
 			ALCcontext* m_context{nullptr};
 			std::unique_ptr<AudioSource> m_defaultSource{nullptr};
+			data::Storage* m_storage = nullptr;
 	};
 
 
diff --git a/include/fggl/gfx/compat.hpp b/include/fggl/gfx/compat.hpp
index eefc4d09cb888da5d59000fecde346fdcca0ff9e..0e860e1d9bfe28ea7e1733ff294432bbd9062151 100644
--- a/include/fggl/gfx/compat.hpp
+++ b/include/fggl/gfx/compat.hpp
@@ -38,7 +38,7 @@ namespace fggl::gfx {
 	struct ecsGlfwModule : ecs3::Module {
 
 		inline explicit
-		ecsGlfwModule(std::shared_ptr<fggl::input::Input> inputs) : context( std::make_shared<GlfwContext>(std::move(inputs))) {
+		ecsGlfwModule(fggl::input::Input* inputs) : context( std::make_shared<GlfwContext>(inputs)) {
 		}
 
 		inline
diff --git a/include/fggl/gfx/ogl/renderer.hpp b/include/fggl/gfx/ogl/renderer.hpp
index 8abc93aae533309475aadcdc3c5494af8081a2a9..4838655cffc65337a04898b3587e6723d40e3855 100644
--- a/include/fggl/gfx/ogl/renderer.hpp
+++ b/include/fggl/gfx/ogl/renderer.hpp
@@ -67,7 +67,7 @@ namespace fggl::gfx {
 	 */
 	class OpenGL4Backend : public Graphics {
 		public:
-			explicit OpenGL4Backend(const Window &owner);
+			explicit OpenGL4Backend(const Window &owner, data::Storage* storage, gui::FontLibrary* fonts);
 			~OpenGL4Backend() override = default;
 
 			// copy bad
@@ -120,6 +120,8 @@ namespace fggl::gfx {
 			std::unique_ptr<ogl4::DebugRenderer> m_debugRenderer;
 			std::unique_ptr<ShaderCache> m_cache;
 			GLuint m_canvasPipeline;
+			data::Storage* m_storage;
+			gui::FontLibrary* m_fontLibrary;
 	};
 
 	using OpenGL4 = OpenGL4Backend;
diff --git a/include/fggl/gfx/ogl/shader.hpp b/include/fggl/gfx/ogl/shader.hpp
index ba3bd188cae96be4d71f621041b8b025598f0426..ef9d89508d430de4ed1732fa9b089846d1642582 100644
--- a/include/fggl/gfx/ogl/shader.hpp
+++ b/include/fggl/gfx/ogl/shader.hpp
@@ -61,7 +61,7 @@ namespace fggl::gfx {
 
 	class ShaderCache {
 		public:
-			ShaderCache(std::shared_ptr<fggl::data::Storage> storage);
+			ShaderCache(fggl::data::Storage* storage);
 			~ShaderCache() = default;
 
 			GLuint load(const ShaderConfig &config);
diff --git a/include/fggl/gfx/ogl4/canvas.hpp b/include/fggl/gfx/ogl4/canvas.hpp
index 3e9de4947cd9a19d1ae29b470261a34da0368fa1..b060e68c0a7c8eba6613d126836233b31d1d4440 100644
--- a/include/fggl/gfx/ogl4/canvas.hpp
+++ b/include/fggl/gfx/ogl4/canvas.hpp
@@ -29,7 +29,7 @@ namespace fggl::gfx::ogl4 {
 
 	class CanvasRenderer {
 		public:
-			CanvasRenderer();
+			CanvasRenderer(gui::FontLibrary* fonts);
 			void render(GLuint shader, const gfx::Paint& paint);
 
 			inline gfx::Bounds bounds() const {
@@ -41,7 +41,7 @@ namespace fggl::gfx::ogl4 {
 			ogl::VertexArray m_vao;
 			ogl::ArrayBuffer m_vertexList;
 			ogl::ElementBuffer m_indexList;
-			gui::FontLibrary m_fonts;
+			gui::FontLibrary* m_fonts;
 			ogl::Texture m_fontTex;
 
 			void renderShapes(const Paint &paint, GLuint shader);
diff --git a/include/fggl/gfx/window.hpp b/include/fggl/gfx/window.hpp
index 262ee1c8e0e57b859a32373c2e56526e363f49c4..a51a4561d1fb4c1449a9baa40dfe79c2239f2762 100644
--- a/include/fggl/gfx/window.hpp
+++ b/include/fggl/gfx/window.hpp
@@ -30,7 +30,7 @@ namespace fggl::gfx {
 
 	class GlfwContext {
 		public:
-			explicit GlfwContext(std::shared_ptr<fggl::input::Input> input);
+			explicit GlfwContext(fggl::input::Input* input);
 			~GlfwContext();
 
 			void pollEvents();
diff --git a/include/fggl/gfx/window_input.hpp b/include/fggl/gfx/window_input.hpp
index 31edd34a36c3d64ed3deabaf96de7861687d2f39..ca74becc65911ebff70b25df5624f8cd88756138 100644
--- a/include/fggl/gfx/window_input.hpp
+++ b/include/fggl/gfx/window_input.hpp
@@ -30,7 +30,7 @@ namespace fggl::gfx {
 				return *instance;
 			}
 
-			inline void setup(std::shared_ptr<input::Input> input) {
+			inline void setup(input::Input* input) {
 				m_inputs = input;
 			}
 
@@ -81,7 +81,7 @@ namespace fggl::gfx {
 			}
 
 		private:
-			std::shared_ptr<input::Input> m_inputs;
+			input::Input* m_inputs;
 
 	};
 
diff --git a/include/fggl/gfx/windowing.hpp b/include/fggl/gfx/windowing.hpp
index 5e8fbf59f8627d30907b70694076e11f5b39631d..250edbf7309c427486ee97f8e924f86f632df170 100644
--- a/include/fggl/gfx/windowing.hpp
+++ b/include/fggl/gfx/windowing.hpp
@@ -45,10 +45,10 @@ namespace fggl::gfx {
 			virtual ~Window() = default;
 			virtual void activate() const = 0;
 
-			template<typename T>
-			void make_graphics() {
+			template<typename T, typename ...Args>
+			void make_graphics(Args... args) {
 				activate();
-				m_graphics = std::make_unique<T>(*this);
+				m_graphics = std::make_unique<T>(*this, args...);
 			}
 
 			// window-related getters
diff --git a/include/fggl/gui/fonts.hpp b/include/fggl/gui/fonts.hpp
index 332467df5e80bd4cbb55cfbf345b2d7aa7a4771c..7a36a60acb25e581698a407ef0777b4bfc7c01dc 100644
--- a/include/fggl/gui/fonts.hpp
+++ b/include/fggl/gui/fonts.hpp
@@ -77,6 +77,10 @@ namespace fggl::gui {
 			FontLibrary& operator=(const FontLibrary&) = delete;
 			FontLibrary& operator=(FontLibrary&&) = delete;
 
+			void setup(data::Storage* storage) {
+				m_storage = storage;
+			}
+
 			inline std::shared_ptr<FontFace> getFont(const std::string& name) {
 				auto fontItr = m_cache.find(name);
 				if ( fontItr != m_cache.end() ) {
@@ -84,8 +88,7 @@ namespace fggl::gui {
 				}
 
 				// need to load the font...
-				auto storage = util::ServiceLocator::instance().get<data::Storage>();
-				auto path = storage->resolvePath(data::StorageType::Data, name);
+				auto path = m_storage->resolvePath(data::StorageType::Data, name);
 
 				FT_Face face;
 				if ( FT_New_Face(m_context, path.string().c_str(), 0, &face) ) {
@@ -101,6 +104,7 @@ namespace fggl::gui {
 
 		private:
 			FT_Library m_context;
+			data::Storage* m_storage;
 			std::map<const std::string, std::shared_ptr<FontFace>> m_cache;
 	};
 
diff --git a/include/fggl/scenes/game.hpp b/include/fggl/scenes/game.hpp
index 660589b95fe95b3852390f3245490a086abe7b57..6d88372dfa32ee2960d9744f53de7d7c92146274 100644
--- a/include/fggl/scenes/game.hpp
+++ b/include/fggl/scenes/game.hpp
@@ -45,7 +45,7 @@ namespace fggl::scenes {
 			}
 
 		private:
-			std::shared_ptr<input::Input> m_input;
+			input::Input* m_input;
 			std::unique_ptr<ecs3::World> m_world;
 			std::unique_ptr<phys::PhysicsEngine> m_phys;
 			std::string m_previous = "menu";
diff --git a/include/fggl/scenes/menu.hpp b/include/fggl/scenes/menu.hpp
index 770d91be127e83c1fc873362c7532c90dc061e96..ecc06eab8a818f72c703dcf6dd4f651fca356f05 100644
--- a/include/fggl/scenes/menu.hpp
+++ b/include/fggl/scenes/menu.hpp
@@ -41,7 +41,7 @@ namespace fggl::scenes {
 			void add(const std::string &label, callback cb);
 
 		private:
-			std::shared_ptr<input::Input> m_inputs;
+			input::Input* m_inputs;
 			std::map<const std::string, callback> m_items;
 
 			// menu state
diff --git a/include/fggl/subsystem/cursed/god_object.hpp b/include/fggl/subsystem/cursed/god_object.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..01e7a2a99d3a82f0f4aed369174048f57e016925
--- /dev/null
+++ b/include/fggl/subsystem/cursed/god_object.hpp
@@ -0,0 +1,140 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 27/06/22.
+// This is the 'quick and dirty' subsystem approach, recommended in 'Game Engine Architecture'
+// Architecturally, this is an abomination, but it works (at least until I build something dependency-based).
+//
+
+#ifndef FGGL_SUBSYSTEM_CURSED_GOD_OBJECT_HPP
+#define FGGL_SUBSYSTEM_CURSED_GOD_OBJECT_HPP
+
+#include <memory>
+
+#include "fggl/subsystem/types.hpp"
+#include "fggl/subsystem/provider.hpp"
+
+#include "fggl/audio/null_audio.hpp"
+
+namespace fggl::subsystem {
+
+	template<typename T>
+	class ServiceContainer {
+		T* m_service = nullptr;
+
+		public:
+			inline void set(T* service) {
+				m_service = service;
+			}
+
+			void release() {
+				if ( m_service != nullptr ) {
+					delete m_service;
+					m_service = nullptr;
+				}
+			}
+
+			[[nodiscard]]
+			inline T* getPtr() const {
+				return m_service;
+			}
+
+			[[nodiscard]]
+			inline T& getRef() const {
+				return *m_service;
+			}
+	};
+
+	class GodObject : public ServiceProvider,
+		private ServiceContainer<data::Storage>,
+		private ServiceContainer<audio::AudioService>
+		{
+		public:
+			GodObject() = default;
+
+			inline void setup() {
+				m_setup = true;
+				ServiceContainer<audio::AudioService>::getPtr()->setup(
+					ServiceContainer<data::Storage>::getPtr()
+				);
+				m_fonts->setup(
+					ServiceContainer<data::Storage>::getPtr()
+				);
+			}
+			inline void teardown() {}
+
+			template<typename T>
+			inline void provide(T* service) {
+				assert(service != nullptr);
+				assert( !m_setup );
+				ServiceContainer<T>::set(service);
+			}
+
+			template<typename T>
+			[[nodiscard]]
+			inline T* get() {
+				return ServiceContainer<T>::get();
+			}
+
+			inline audio::AudioService* getAudio() override {
+				assert(m_setup);
+				return ServiceContainer<audio::AudioService>::getPtr();
+			}
+
+			inline void setFontLibrary(gui::FontLibrary* fontLibrary) {
+				assert( !m_setup );
+				m_fonts = fontLibrary;
+			}
+
+			inline gui::FontLibrary* getFontLibrary() override {
+				assert(m_setup);
+				return m_fonts;
+			}
+
+			inline void setInput(input::Input* input){
+				assert( !m_setup );
+				m_input = input;
+			}
+
+			input::Input* getInput() override {
+				assert(m_setup);
+				return m_input;
+			}
+
+			data::Storage* getStorage() override {
+				assert(m_setup);
+				return ServiceContainer<data::Storage>::getPtr();
+			}
+
+			inline void setTypeRegistry(ecs3::TypeRegistry* registry) {
+				assert( !m_setup );
+				m_types = registry;
+			}
+
+			ecs3::TypeRegistry* getTypeRegistry() override {
+				assert(m_setup);
+				return m_types;
+			}
+
+		private:
+			bool m_setup = false;
+			gui::FontLibrary* m_fonts = nullptr;
+			ecs3::TypeRegistry* m_types = nullptr;
+			input::Input* m_input = nullptr;
+	};
+
+} // namespace fggl::subsystem
+
+#endif //FGGL_SUBSYSTEM_CURSED_GOD_OBJECT_HPP
diff --git a/include/fggl/subsystem/provider.hpp b/include/fggl/subsystem/provider.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2367bff7ffe5a2569da517cb553e6ff07881345b
--- /dev/null
+++ b/include/fggl/subsystem/provider.hpp
@@ -0,0 +1,40 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 27/06/22.
+//
+
+#ifndef FGGL_SUBSYSTEM_PROVIDER_HPP
+#define FGGL_SUBSYSTEM_PROVIDER_HPP
+
+#include "fggl/audio/audio.hpp"
+#include "fggl/gui/gui.hpp"
+#include "fggl/ecs3/types.hpp"
+#include "fggl/input/input.hpp"
+
+namespace fggl::subsystem {
+
+	class ServiceProvider {
+		public:
+			virtual audio::AudioService* getAudio() = 0;
+			virtual gui::FontLibrary* getFontLibrary() = 0;
+			virtual input::Input* getInput() = 0;
+			virtual data::Storage* getStorage() = 0;
+			virtual ecs3::TypeRegistry* getTypeRegistry() = 0;
+	};
+
+} // namespace fggl::subsystem
+
+#endif //FGGL_SUBSYSTEM_PROVIDER_HPP
diff --git a/include/fggl/subsystem/subsystem.hpp b/include/fggl/subsystem/subsystem.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..6765f0227788752c1d84fa47e15246439217b986
--- /dev/null
+++ b/include/fggl/subsystem/subsystem.hpp
@@ -0,0 +1,32 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 27/06/22.
+//
+
+#ifndef FGGL_SUBSYSTEM_SUBSYSTEM_HPP
+#define FGGL_SUBSYSTEM_SUBSYSTEM_HPP
+
+#include "fggl/subsystem/cursed/god_object.hpp"
+
+namespace fggl::subsystem {
+
+	using SubsystemManager = GodObject;
+
+
+
+} // namespace fggl::subsystem
+
+#endif //FGGL_SUBSYSTEM_SUBSYSTEM_HPP
diff --git a/include/fggl/subsystem/types.hpp b/include/fggl/subsystem/types.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e9d58cbf393c6173f8cc75656dfc3005ca323b77
--- /dev/null
+++ b/include/fggl/subsystem/types.hpp
@@ -0,0 +1,36 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 27/06/22.
+//
+
+#ifndef FGGL_SUBSYSTEM_TYPES_HPP
+#define FGGL_SUBSYSTEM_TYPES_HPP
+
+
+namespace fggl::subsystem {
+
+	class ServiceProvider;
+
+	class Subsystem {
+			virtual ~Subsystem() = default;
+
+			virtual void setup(ServiceProvider& provider) = 0;
+			virtual void teardown(ServiceProvider& provider) = 0;
+	};
+
+} // namespace fggl::subsystem
+
+#endif //FGGL_SUBSYSTEM_TYPES_HPP
diff --git a/include/fggl/util/service.hpp b/include/fggl/util/service.hpp
index bff74fcfa45af62f20f09326bafa149563d77414..a22bd926118fa405014606006ed7e2a4029d0b75 100644
--- a/include/fggl/util/service.hpp
+++ b/include/fggl/util/service.hpp
@@ -16,6 +16,9 @@
 // Created by webpigeon on 20/11/2021.
 //
 
+// quick and dirty way to disable the class
+#define FGGL_UTIL_SERVICE_HPP
+
 #ifndef FGGL_UTIL_SERVICE_HPP
 #define FGGL_UTIL_SERVICE_HPP