diff --git a/include/fggl/assets/loader.hpp b/include/fggl/assets/loader.hpp
index beedcc2711aa337dc82b417ca8da18a25bd57d1c..6c104bd64c5ffe7d8a22a3a4777cec4812db250f 100644
--- a/include/fggl/assets/loader.hpp
+++ b/include/fggl/assets/loader.hpp
@@ -80,39 +80,23 @@ namespace fggl::assets {
 					return;
 				}
 
-				// FIXME use the fancy dependency resolution algorithm from the module system
-				std::vector<AssetID> loadOrder;
-				std::stack<AssetID> openSet;
-				openSet.push(asset);
-				while ( !openSet.empty() ) {
-					auto current = openSet.top();
-					openSet.pop();
-
-					if ( !m_checkin->exists(current) ) {
-						debug::warning("attempted to load chain with unknown assert, {} - abort!", current);
-						return;
-					}
-
-					// this WILL (probably) break if an asset ends up in the chain twice
-					loadOrder.push_back( current );
-					const auto& record = m_checkin->find(current);
-					for ( const auto& dep : record.m_requires ) {
-						openSet.push( dep );
-					}
-				}
 
+				std::queue<AssetID> loadOrder;
+				m_checkin->loadOrder(asset, loadOrder);
 				processChain(loadOrder, userPtr);
 			}
 
-			void processChain( std::vector<AssetID>& loadOrder, void* userPtr = nullptr ) {
+			void processChain( std::queue<AssetID>& loadOrder, void* userPtr = nullptr ) {
 				if ( loadOrder.empty() ) {
 					return;
 				}
 
 				debug::info("Starting chain load");
-				for ( auto it = loadOrder.rbegin(); it < loadOrder.rend(); ++it  ) {
-					debug::info(" CHAIN -> loading {}", *it );
-					load( *it, userPtr );
+				while( !loadOrder.empty() ) {
+					auto it = loadOrder.front();
+					debug::info(" CHAIN -> loading {}", it );
+					load( it, userPtr );
+					loadOrder.pop();
 				}
 				debug::info("Ended chain loader");
 			}
diff --git a/include/fggl/assets/packed/adapter.hpp b/include/fggl/assets/packed/adapter.hpp
index d2299850391801620a421fd26b26602587ce2dc9..a5cbab2871b75fac516edaebe46c0c381edd9b37 100644
--- a/include/fggl/assets/packed/adapter.hpp
+++ b/include/fggl/assets/packed/adapter.hpp
@@ -25,6 +25,7 @@
 
 #include "fggl/assets/packed/direct.hpp"
 #include "fggl/data/storage.hpp"
+#include "fggl/ds/graph.hpp"
 
 namespace fggl::assets {
 
@@ -95,6 +96,10 @@ namespace fggl::assets {
 				return file.m_path;
 			}
 
+			void loadOrder( AssetID id, std::queue<AssetID>& order) {
+				m_requires.getOrderPartialRev(id, order);
+			}
+
 			void discover( const char* packName, bool useCache = false, bool updateCache = true) {
 				if ( m_packs.contains(packName) ) {
 					return;
@@ -167,6 +172,7 @@ namespace fggl::assets {
 			data::Storage* m_storage;
 			RawCheckin* m_checkin;
 			std::map<AssetID, ResourceRecord> m_files;
+			ds::DirectedGraph<AssetID> m_requires;
 
 			struct PackInfo {
 				std::filesystem::path rootDir;
@@ -204,6 +210,8 @@ namespace fggl::assets {
 						// store the resulting data
 						m_files[rr.assetID] = rr;
 						packFiles.push_back( rr.assetID );
+						m_requires.addEdges( rr.assetID, rr.m_requires );
+
 						debug::trace("discovered {} ({}) from pack '{}'", rr.assetID, relPath.c_str(), packName.c_str() );
 						break;
 					}
@@ -256,6 +264,7 @@ namespace fggl::assets {
 				};
 				m_files[ rr.assetID ] = rr;
 				m_packs[ packRoot.filename() ].assets.push_back( rr.assetID );
+				m_requires.addEdges( rr.assetID, depList );
 				debug::trace("discovered {} ({}) from pack {}", rr.assetID.get(), fullPath.c_str(), packRoot.filename().c_str() );
 			}
 
diff --git a/include/fggl/ds/graph.hpp b/include/fggl/ds/graph.hpp
index f88ff5c61adf292b1e43beffc2b9c64adbdb747d..8675c08564ca7afafff015bdf702f1bb5e77edc6 100644
--- a/include/fggl/ds/graph.hpp
+++ b/include/fggl/ds/graph.hpp
@@ -40,7 +40,7 @@ namespace fggl::ds {
 			 * @param start the entry which depends something else
 			 * @param end the thing it depends on
 			 */
-			inline void addEdge(T start, const T end) {
+			inline void addEdge(const T start, const T end) {
 				m_edges[start].push_back(end);
 				m_edges[end];
 			}
@@ -48,7 +48,7 @@ namespace fggl::ds {
 			/**
 			 * Add a single vertex to the graph.
 			 */
-			 inline void addVertex(T vertex) {
+			 inline void addVertex(const T vertex) {
 				 m_edges[vertex];
 			 }
 
@@ -61,7 +61,7 @@ namespace fggl::ds {
 			 * @param name the entry having dependencies added
 			 * @param dependencies the things it depends on
 			 */
-			void addEdges(const T &name, const std::vector<T> &dependencies) {
+			void addEdges(const T name, const std::vector<T> &dependencies) {
 				auto existing = m_edges.find(name);
 				if (existing == m_edges.end()) {
 					m_edges[name] = dependencies;
@@ -99,6 +99,12 @@ namespace fggl::ds {
 				return true;
 			}
 
+			bool getOrderPartial(T first, std::stack<T> &stack) {
+				std::set<T> visited{};
+				sortUtil(first, visited, stack);
+				return true;
+			}
+
 			bool getOrderRev(std::queue<T> &stack) {
 				std::set<T> visited{};
 
@@ -111,6 +117,12 @@ namespace fggl::ds {
 				return true;
 			}
 
+			bool getOrderPartialRev(T first, std::queue<T>& queue) {
+				std::set<T> visited{};
+				sortUtilRev(first, visited, queue);
+				return true;
+			}
+
 		private:
 			std::map<T, std::vector<T>> m_edges;