diff --git a/fggl/CMakeLists.txt b/fggl/CMakeLists.txt
index 579475433394a9830ffdba9ad9f70f691fb04b5d..d7c20d199fcb7ff0c09edae4876fc100753f7d62 100644
--- a/fggl/CMakeLists.txt
+++ b/fggl/CMakeLists.txt
@@ -31,6 +31,10 @@ if (CLANG_TIDY_FOUND)
     set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=*,-llvmlibc-*,-fuchsia-*,-cppcoreguidelines-*,-android-*,-llvm-*,-altera-*,-modernize-use-trailing-return-type)
 endif ()
 
+# the important stuff everything else uses
+add_subdirectory(math)
+add_subdirectory(util)
+
 target_sources(${PROJECT_NAME}
     PRIVATE
         app.cpp
@@ -58,8 +62,6 @@ target_sources(${PROJECT_NAME}
         gui/fonts.cpp
 )
 
-add_subdirectory(math)
-
 # yaml-cpp for configs and storage
 find_package(yaml-cpp)
 target_link_libraries(fggl PUBLIC yaml-cpp)
diff --git a/fggl/util/CMakeLists.txt b/fggl/util/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1cb7bb3a9ef511c8e597acb0df303b3810485670
--- /dev/null
+++ b/fggl/util/CMakeLists.txt
@@ -0,0 +1,4 @@
+target_sources(fggl
+    PRIVATE
+        guid.cpp
+)
\ No newline at end of file
diff --git a/fggl/util/guid.cpp b/fggl/util/guid.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..569353daa74538496ab20a0ecd41abcbb2968c78
--- /dev/null
+++ b/fggl/util/guid.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 23/07/22.
+//
+
+#include <map>
+#include <string>
+#include <cassert>
+
+#include "fggl/util/guid.hpp"
+
+namespace fggl::util {
+	static std::map<GUID, std::string> guidTable;
+
+	GUID internString(const char* str) {
+		GUID guid = make_guid(str);
+		auto tableValue = guidTable.find(guid);
+		if (tableValue != guidTable.end()) {
+			assert(tableValue->second == str);
+		} else {
+			guidTable[guid] = str;
+		}
+	}
+
+	std::string guidToString(GUID guid) {
+		auto tableValue = guidTable.find(guid);
+		if (tableValue != guidTable.end()) {
+			return tableValue->second;
+		} else {
+			return "FGGL_UNKNOWN_GUID";
+		}
+	}
+}
diff --git a/include/fggl/util/guid.hpp b/include/fggl/util/guid.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..77b2fc313f9ecb0f48c0032c77c1e9a32e19ee3d
--- /dev/null
+++ b/include/fggl/util/guid.hpp
@@ -0,0 +1,66 @@
+/*
+ * 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 23/07/22.
+//
+
+#ifndef FGGL_UTIL_GUID_HPP
+#define FGGL_UTIL_GUID_HPP
+
+#include <cstdint>
+#include "fggl/util/safety.hpp"
+
+namespace fggl::util {
+
+	using GUID = OpaqueName<std::uint64_t, struct GuidTag>;
+
+	constexpr uint32_t FNV_PRIME_32 = 0x01000193;
+	constexpr uint32_t FNV_OFFSET_BASIS_32 = 0x811c9dc5;
+	constexpr uint64_t FNV_PRIME_64 = 0x00000100000001B3;
+	constexpr uint64_t FNV_OFFSET_BASIS_64 = 0xcbf29ce484222325;
+
+	constexpr uint32_t hash_fnv0a_32(const char* str) {
+		uint32_t hash = FNV_OFFSET_BASIS_32;
+		for (int i = 0; str[i] != '\0'; i++) {
+			hash = hash ^ str[i];
+			hash = hash * FNV_PRIME_32;
+		}
+		return hash;
+	}
+
+	constexpr uint64_t hash_fnv0a_64(const char* str) {
+		uint64_t hash = FNV_OFFSET_BASIS_64;
+		for (int i = 0; str[i] != '\0'; i++) {
+			hash = hash ^ str[i];
+			hash = hash * FNV_PRIME_64;
+		}
+		return hash;
+	}
+
+	constexpr GUID make_guid(const char* str) {
+		return GUID::make(hash_fnv0a_64(str));
+	}
+
+	constexpr GUID operator ""_fid(const char* str) {
+		return make_guid(str);
+	}
+
+	// debug-only functions
+	GUID internString(const char* str);
+	std::string guidToString(GUID guid);
+
+} // namespace fggl::util
+
+#endif //FGGL_UTIL_GUID_HPP