diff --git a/DevScreenshots/3. Textured Cube With Assets Read From A Custom Format.png b/DevScreenshots/3. Textured Cube With Assets Read From A Custom Format.png
new file mode 100644
index 0000000..f899d8c
Binary files /dev/null and b/DevScreenshots/3. Textured Cube With Assets Read From A Custom Format.png differ
diff --git a/Game/Game.vcxproj b/Game/Game.vcxproj
index cc6dc90..3c4b186 100644
--- a/Game/Game.vcxproj
+++ b/Game/Game.vcxproj
@@ -109,7 +109,7 @@
       nf.res;%(AdditionalDependencies)
     
     
-      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
+      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
     
   
   
@@ -135,7 +135,7 @@
       nf.res;%(AdditionalDependencies)
     
     
-      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
+      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
     
   
   
@@ -157,7 +157,7 @@
       nf.res;%(AdditionalDependencies)
     
     
-      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
+      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
     
   
   
@@ -183,7 +183,7 @@
       nf.res;%(AdditionalDependencies)
     
     
-      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
+      cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\"
     
   
   
@@ -203,7 +203,7 @@
   
   
     
-      <_delete Include="$(OutDir)**\*"/>
+      <_delete Include="$(OutDir)**\*" />
     
     
   
diff --git a/NFPackCreator/NFPackCreator.vcxproj.user b/NFPackCreator/NFPackCreator.vcxproj.user
index 5e75a14..67e52a5 100644
--- a/NFPackCreator/NFPackCreator.vcxproj.user
+++ b/NFPackCreator/NFPackCreator.vcxproj.user
@@ -6,7 +6,6 @@
   
     $(OutDir)
     WindowsLocalDebugger
-    -h
   
   
     $(OutDir)
diff --git a/NFPackCreator/src/main.cpp b/NFPackCreator/src/main.cpp
index ebbed33..7a27b3e 100644
--- a/NFPackCreator/src/main.cpp
+++ b/NFPackCreator/src/main.cpp
@@ -33,7 +33,7 @@ void Success(const std::string& in) {
 
 std::string readFile(const std::string& filename) {
 	std::ifstream in;
-	in.open(filename);
+	in.open(filename, std::ios::binary);
 	if (!in)
 		Error("File \"" + (std::string)filename + (std::string)"\" could not be read!");
 	std::stringstream ss;
@@ -49,13 +49,15 @@ std::string readFile(const std::string& filename) {
 
 void writeFile(const std::string& filename, const std::string& in, bool encrypted) {
 	std::ofstream out;
-	out.open(filename);
+	out.open(filename, std::ios::binary);
 	if (!out)
 		Error("File \"" + (std::string)filename + (std::string)"\" could not be written!");
 	std::string write(in);
 	if (encrypted) {
-		for (unsigned int i = 0; i < write.size(); i++)
-			write[i] = write[i] + 100;
+		for (unsigned int i = 0; i < write.size(); i++) {
+			char temp = write[i] + 100;
+			write[i] = temp;
+		}
 		write.insert(0, "NFEF");
 	}
 	out << write;
@@ -82,7 +84,7 @@ int main(int argc, char* argv[]) {
 			continue;
 		std::string filename = currDir.path().filename().string().append(".nfpack");
 		Log("Creating pack \"" + filename + (std::string)"\"");
-		std::ifstream in;
+		std::string currFileContents;
 		std::stringstream out;
 		unsigned int fileCount = 0;
 		for (const auto& curr : std::filesystem::recursive_directory_iterator(currDir)) {
@@ -93,15 +95,12 @@ int main(int argc, char* argv[]) {
 				Error("File \"" + relative.string() + (std::string)"\" is not of supported type!");
 			Log("Current file: " + relative.string());
 
-			in.open(curr.path(), std::ios::binary);
-			if (!in)
-				Error("Couldn't open \"" + relative.string() + (std::string)"\"!");
+			currFileContents = readFile(curr.path().string());
 			if (out.rdbuf()->in_avail() != 0)
 				out << "\n";
 			out << "#NFASSET " + curr.path().filename().string();
 			out << "\n";
-			out << in.rdbuf();
-			in.close();
+			out << currFileContents;
 			fileCount++;
 		}
 		if (fileCount == 0) {
@@ -114,6 +113,8 @@ int main(int argc, char* argv[]) {
 	}
 	if (dirCount > 0)
 		Log("Wrote " + std::to_string(dirCount) + (std::string)" asset pack(s).");
+	else
+		Log("No directories found!");
 	Log("Done");
 	std::this_thread::sleep_for(std::chrono::seconds(2));
 	return 0;
diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp
index ef17049..2c376e5 100644
--- a/NothinFancy/src/Application.cpp
+++ b/NothinFancy/src/Application.cpp
@@ -144,7 +144,7 @@ namespace nf {
 			RegisterClass(&wclass);
 		}
 		else
-			Error("Cannot run two NF applications at once!");
+			Error("Cannot run multiple NF applications concurrently!");
 	}
 
 	RECT Application::getWindowRect() const {
diff --git a/NothinFancy/src/Assets.cpp b/NothinFancy/src/Assets.cpp
index f7eecba..e8e85b6 100644
--- a/NothinFancy/src/Assets.cpp
+++ b/NothinFancy/src/Assets.cpp
@@ -1,5 +1,6 @@
 #include "Assets.h"
 
+#include "Model.h"
 #include "Utility.h"
 
 namespace nf {
@@ -7,14 +8,12 @@ namespace nf {
 
 	}
 
-	AGeometry::~AGeometry() {
-		delete[] m_vertexBufferData;
-		delete[] m_indexBufferData;
-		delete[] m_textureCoordinatesBufferData;
+	AModel::~AModel() {
+		delete[] data;
 	}
 
 	ATexture::~ATexture() {
-		delete[] m_data;
+		delete[] data;
 	}
 
 	AssetPack::AssetPack() {
@@ -22,8 +21,59 @@ namespace nf {
 	}
 
 	void AssetPack::load(const char* packName) {
-		std::string path = "assets/" + (std::string)packName + ".nfpack";
-		std::string contents = readFile(path);
+		std::string path = "assets/" + (std::string)packName;
+		std::string packContents = readFile(path);
+		while (packContents.size()) {
+			unsigned int startingPos = packContents.find_first_of("#NFASSET ") + 9;
+			packContents = packContents.substr(9);
+			unsigned int endAssetNamePos = packContents.find_first_of('\n');
+			std::string assetName = packContents.substr(0, endAssetNamePos);
+			packContents = packContents.substr(endAssetNamePos + 1);
+			unsigned int extensionPos = assetName.find_first_of('.');
+			std::string extension = assetName.substr(extensionPos + 1);
+			std::string assetContents;
+			unsigned int nextAssetPos = packContents.find("#NFASSET ");
+			if (nextAssetPos != std::string::npos) {
+				assetContents = packContents.substr(0, nextAssetPos - 1);
+				packContents = packContents.substr(nextAssetPos);
+			}
+			else {
+				assetContents = packContents;
+				packContents = "";
+			}
+			size_t assetSize = assetContents.size();
+
+			if (extension == "obj") {
+				AModel* geometry = new AModel;
+				geometry->data = new char[assetSize + 1];
+				std::memcpy(geometry->data, &assetContents[0], assetSize);
+				geometry->data[assetSize] = '\0';
+				geometry->alreadyLoaded = false;
+				geometry->loadedModel = nullptr;
+				m_assets[assetName] = geometry;
+				continue;
+			}
+			if (extension == "png") {
+				ATexture* texture = new ATexture;
+				texture->data = new unsigned char[assetSize];
+				std::memcpy(texture->data, &assetContents[0], assetSize);
+				texture->size = assetSize;
+				m_assets[assetName] = texture;
+				continue;
+			}
+			Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!");
+		}
+	}
+
+	Asset* AssetPack::operator[](const char* in) {
+		if (m_assets.find(in) == m_assets.end())
+			Error("Could not find asset \"" + (std::string)in + (std::string)"\" in asset pack!");
+		return m_assets[in];
+	}
+	Asset* AssetPack::operator[](std::string& in) {
+		if (m_assets.find(in) == m_assets.end())
+			Error("Could not find asset \"" + in + (std::string)"\" in asset pack!");
+		return m_assets[in];
 	}
 
 	AssetPack::~AssetPack() {
diff --git a/NothinFancy/src/Renderer/Drawable/Entity.cpp b/NothinFancy/src/Renderer/Drawable/Entity.cpp
index dedd125..083aaf9 100644
--- a/NothinFancy/src/Renderer/Drawable/Entity.cpp
+++ b/NothinFancy/src/Renderer/Drawable/Entity.cpp
@@ -1,5 +1,9 @@
 #include "Entity.h"
 
+#include
+
+#include "Utility.h"
+
 namespace nf {
 	Entity::Entity() :
 		m_model(nullptr),
@@ -10,25 +14,40 @@ namespace nf {
 
 	}
 
-	void Entity::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const char* textureName) {
+	void Entity::create(Asset* modelAsset, Asset* textureAsset) {
+		AModel& model = *(AModel*)modelAsset;
+		if (model.alreadyLoaded) {
+			m_model = model.loadedModel;
+			return;
+		}
+		if (!textureAsset)
+			Error("No texture given to Entity create function on new model load!");
+		ATexture& texture = *(ATexture*)textureAsset;
+		std::string obj = model.data;
 		m_model = new Model;
-		m_model->create(vertexBufferData, vertexBufferSize, indexBufferData, indexBufferCount, textureCoordinatesBufferData, textureCoordinatesBufferSize, textureName);
-		//TODO: Replace this with getting the information from the AGeometry and ATexture structs
+		std::vector vb;
+		std::vector ib;
+		size_t ibCount = 0;
+		std::vector tc;
+		parseOBJ(obj, vb, ib, ibCount, tc);
+		m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &tc[0], tc.size() * sizeof(float), texture.data, texture.size);
+		model.alreadyLoaded = true;
+		model.loadedModel = m_model;
 	}
 
-	void Entity::setPosition(float x, float y, float z) {
+	void Entity::setPosition(double x, double y, double z) {
 		m_position = { x, y, z };
 	}
 
-	void Entity::setRotation(float x, float y, float z) {
+	void Entity::setRotation(double x, double y, double z) {
 		m_rotation = { x, y, z };
 	}
 
-	void Entity::setScale(float x) {
+	void Entity::setScale(double x) {
 		m_rotation = { x, x, x };
 	}
 
-	void Entity::setScale(float x, float y, float z) {
+	void Entity::setScale(double x, double y, double z) {
 		m_scale = { x, y, z };
 	}
 
@@ -45,9 +64,9 @@ namespace nf {
 	void Entity::setModelMatrix(Shader* shader) {
 		glm::mat4 model(1.0f);
 		model = glm::translate(model, glm::vec3(m_position.x, m_position.y, m_position.z));
-		model = glm::rotate(model, glm::radians(m_rotation.x), glm::vec3(1.0, 0.0, 0.0));
-		model = glm::rotate(model, glm::radians(m_rotation.y), glm::vec3(0.0, 1.0, 0.0));
-		model = glm::rotate(model, glm::radians(m_rotation.z), glm::vec3(0.0, 0.0, 1.0));
+		model = glm::rotate(model, glm::radians((float)m_rotation.x), glm::vec3(1.0, 0.0, 0.0));
+		model = glm::rotate(model, glm::radians((float)m_rotation.y), glm::vec3(0.0, 1.0, 0.0));
+		model = glm::rotate(model, glm::radians((float)m_rotation.z), glm::vec3(0.0, 0.0, 1.0));
 		model = glm::scale(model, glm::vec3(m_scale.x, m_scale.y, m_scale.z));
 		shader->setUniform("model", model);
 	}
diff --git a/NothinFancy/src/Renderer/Drawable/Model.cpp b/NothinFancy/src/Renderer/Drawable/Model.cpp
index 065fdfe..e20b67a 100644
--- a/NothinFancy/src/Renderer/Drawable/Model.cpp
+++ b/NothinFancy/src/Renderer/Drawable/Model.cpp
@@ -6,18 +6,17 @@ namespace nf {
 	Model::Model() {
 	}
 
-	void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const char* textureName) {
+	void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const unsigned char* textureData, size_t textureSize) {
 		m_vao = new VertexArray;
 		m_vao->addBuffer(vertexBufferData, vertexBufferSize);
-		m_vao->push(2);
-		//TODO: Change this to 3
+		m_vao->push(3);
 		m_vao->finishBufferLayout();
-		if (textureCoordinatesBufferData && textureCoordinatesBufferSize && textureName) {
+		if (textureCoordinatesBufferData && textureCoordinatesBufferSize && textureData) {
 			m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize);
 			m_vao->push(2);
 			m_vao->finishBufferLayout();
 			m_texture = new Texture;
-			m_texture->create(textureName);
+			m_texture->create(textureData, textureSize);
 		}
 		m_ib = new IndexBuffer(indexBufferData, indexBufferCount);
 	}
diff --git a/NothinFancy/src/Renderer/Texture.cpp b/NothinFancy/src/Renderer/Texture.cpp
index c5b192b..eff2c0f 100644
--- a/NothinFancy/src/Renderer/Texture.cpp
+++ b/NothinFancy/src/Renderer/Texture.cpp
@@ -11,18 +11,17 @@ namespace nf {
 		glGenTextures(1, &m_id);
 	}
 
-	void Texture::create(const char* textureName) {
+	void Texture::create(const unsigned char* textureData, size_t textureSize) {
 		int width, height, nChannels;
 		stbi_set_flip_vertically_on_load(true);
-		unsigned char* texture = stbi_load(textureName, &width, &height, &nChannels, 0);
-		//TODO: Load from memory
+		unsigned char* texture = stbi_load_from_memory(textureData, textureSize, &width, &height, &nChannels, 0);
 		if (!texture)
-			Error("Texture \"" + (std::string)textureName + "\" failed to load from memory!");
+			Error("Texture failed to load from memory!");
 		glBindTexture(GL_TEXTURE_2D, m_id);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
-		//glGenerateMipmap(GL_TEXTURE_2D);
+		glGenerateMipmap(GL_TEXTURE_2D);
 		stbi_image_free(texture);
 	}
 
diff --git a/NothinFancy/src/Utility.cpp b/NothinFancy/src/Utility.cpp
index 859c525..a25c418 100644
--- a/NothinFancy/src/Utility.cpp
+++ b/NothinFancy/src/Utility.cpp
@@ -3,6 +3,7 @@
 #include 
 #include 
 #include 
+#include