diff --git a/ScuffedMinecraft/ScuffedMinecraft.vcxproj b/ScuffedMinecraft/ScuffedMinecraft.vcxproj
index 0d702c2..bcfb7dc 100644
--- a/ScuffedMinecraft/ScuffedMinecraft.vcxproj
+++ b/ScuffedMinecraft/ScuffedMinecraft.vcxproj
@@ -158,7 +158,6 @@
     <ClCompile Include="src\Camera.cpp" />
     <ClCompile Include="src\Chunk.cpp" />
     <ClCompile Include="src\ChunkData.cpp" />
-    <ClCompile Include="src\ChunkPos.cpp" />
     <ClCompile Include="src\NoiseSettings.cpp" />
     <ClCompile Include="src\Physics.cpp" />
     <ClCompile Include="src\Planet.cpp" />
@@ -182,7 +181,6 @@
     <ClInclude Include="src\Camera.h" />
     <ClInclude Include="src\Chunk.h" />
     <ClInclude Include="src\ChunkData.h" />
-    <ClInclude Include="src\ChunkPos.h" />
     <ClInclude Include="src\NoiseSettings.h" />
     <ClInclude Include="src\Physics.h" />
     <ClInclude Include="src\Planet.h" />
diff --git a/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters b/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters
index 45330a1..6c24072 100644
--- a/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters
+++ b/ScuffedMinecraft/ScuffedMinecraft.vcxproj.filters
@@ -75,9 +75,6 @@
     <ClCompile Include="src\Physics.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\ChunkPos.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="src\ChunkData.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -146,9 +143,6 @@
     <ClInclude Include="src\Physics.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="src\ChunkPos.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="src\ChunkData.h">
       <Filter>Header Files</Filter>
     </ClInclude>
diff --git a/ScuffedMinecraft/src/Application.cpp b/ScuffedMinecraft/src/Application.cpp
index eeec24a..226871d 100644
--- a/ScuffedMinecraft/src/Application.cpp
+++ b/ScuffedMinecraft/src/Application.cpp
@@ -27,19 +27,19 @@
 #include "Physics.h"
 
 void framebufferSizeCallback(GLFWwindow* window, int width, int height);
-void processInput(GLFWwindow* window);
+void processInput(GLFWwindow* window, ImGuiIO& io);
 void mouse_callback(GLFWwindow* window, double xpos, double ypos);
 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
 void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
+void updateAvgFps(ImGuiIO& io);
 
-float deltaTime = 0.0f;
-float lastFrame = 0.0f;
-int fpsCount = 0;
-std::chrono::steady_clock::time_point fpsStartTime;
-float avgFps = 0;
-float lowestFps = -1;
-float highestFps = -1;
-float lastX = 400, lastY = 300;
+double currentTime = 0.0;
+float avgFps = -1.f;
+#define FPS_SAMPLES 10 // How many samples should be taken to calculate the avgFps
+float fpsSamples[FPS_SAMPLES];
+float minFps = FLT_MAX; // If this isn't big enough then you have a killer pc
+float maxFps = -1.f;
+float lastX = 400.f, lastY = 300.f;
 bool firstMouse = true;
 
 bool menuMode = false;
@@ -62,31 +62,31 @@ GLuint depthTexture;
 
 float rectangleVertices[] =
 {
-	 // Coords     // TexCoords
-	 1.0f, -1.0f,  1.0f, 0.0f,
-	-1.0f, -1.0f,  0.0f, 0.0f,
-	-1.0f,  1.0f,  0.0f, 1.0f,
+	// Coords     // TexCoords
+	1.0f, -1.0f,  1.0f, 0.0f,
+   -1.0f, -1.0f,  0.0f, 0.0f,
+   -1.0f,  1.0f,  0.0f, 1.0f,
 
-	 1.0f,  1.0f,  1.0f, 1.0f,
-	 1.0f, -1.0f,  1.0f, 0.0f,
-	-1.0f,  1.0f,  0.0f, 1.0f
+	1.0f,  1.0f,  1.0f, 1.0f,
+	1.0f, -1.0f,  1.0f, 0.0f,
+   -1.0f,  1.0f,  0.0f, 1.0f
 };
 
-float outlineVertices[] = 
+float outlineVertices[] =
 {
 	-.001f, -.001f, -.001f,  1.001f, -.001f, -.001f,
-    1.001f, -.001f, -.001f,  1.001f, 1.001f, -.001f,
+	1.001f, -.001f, -.001f,  1.001f, 1.001f, -.001f,
 	1.001f, 1.001f, -.001f,  -.001f, 1.001f, -.001f,
 	-.001f, 1.001f, -.001f,  -.001f, -.001f, -.001f,
-	   		   		   							
+
 	-.001f, -.001f, -.001f,  -.001f, -.001f, 1.001f,
 	-.001f, -.001f, 1.001f,  -.001f, 1.001f, 1.001f,
 	-.001f, 1.001f, 1.001f,  -.001f, 1.001f, -.001f,
-	   		   		   							
+
 	1.001f, -.001f, -.001f,  1.001f, -.001f, 1.001f,
 	1.001f, -.001f, 1.001f,  1.001f, 1.001f, 1.001f,
 	1.001f, 1.001f, 1.001f,  1.001f, 1.001f, -.001f,
-	   		   		   							
+
 	-.001f, -.001f, 1.001f,  1.001f, -.001f, 1.001f,
 	-.001f, 1.001f, 1.001f,  1.001f, 1.001f, 1.001f,
 };
@@ -96,13 +96,13 @@ float crosshairVertices[] =
 	windowX / 2 - 13.5, windowY / 2 - 13.5,  0.0f, 0.0f,
 	windowX / 2 + 13.5, windowY / 2 - 13.5,  1.0f, 0.0f,
 	windowX / 2 + 13.5, windowY / 2 + 13.5,  1.0f, 1.0f,
-				  					 
+
 	windowX / 2 - 13.5, windowY / 2 - 13.5,  0.0f, 0.0f,
 	windowX / 2 - 13.5, windowY / 2 + 13.5,  0.0f, 1.0f,
 	windowX / 2 + 13.5, windowY / 2 + 13.5,  1.0f, 1.0f,
 };
 
-int main(int argc, char *argv[])
+int main(int argc, char* argv[])
 {
 #ifdef LINUX
 	char* resolved_path = realpath(argv[0], NULL);
@@ -137,7 +137,7 @@ int main(int argc, char *argv[])
 	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
 	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-	
+
 	// Create window
 	GLFWwindow* window = glfwCreateWindow(windowX, windowY, "Scuffed Minecraft", nullptr, nullptr);
 	if (window == nullptr)
@@ -263,7 +263,7 @@ int main(int argc, char *argv[])
 	glGenTextures(1, &texture);
 	glActiveTexture(GL_TEXTURE0);
 	glBindTexture(GL_TEXTURE_2D, texture);
-	 
+
 	// Set texture parameters
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -318,6 +318,10 @@ int main(int argc, char *argv[])
 
 	glm::mat4 ortho = glm::ortho(0.0f, (float)windowX, (float)windowY, 0.0f, 0.0f, 10.0f);
 
+	std::fill(fpsSamples, fpsSamples + FPS_SAMPLES, -1.0f);
+	for (int i = 0; i < FPS_SAMPLES; i++)
+		std::cout << fpsSamples[i] << std::endl;
+
 	// Initialize ImGui
 	IMGUI_CHECKVERSION();
 	ImGui::CreateContext();
@@ -326,39 +330,26 @@ int main(int argc, char *argv[])
 	ImGui_ImplGlfw_InitForOpenGL(window, true);
 	ImGui_ImplOpenGL3_Init("#version 330");
 
-	fpsStartTime = std::chrono::steady_clock::now();
-
 	while (!glfwWindowShouldClose(window))
 	{
-		// Delta Time
-		float currentFrame = glfwGetTime();
-		deltaTime = currentFrame - lastFrame;
-		lastFrame = currentFrame;
+		// Get time
+		currentTime = glfwGetTime();
+
+		// Fetching max/min fps
+		if (minFps > io.Framerate)
+			minFps = io.Framerate;
+		if (maxFps < io.Framerate)
+			maxFps = io.Framerate;
+		updateAvgFps(io);
 
-		// FPS Calculations
-		float fps = 1.0f / deltaTime;
-		if (lowestFps == -1 || fps < lowestFps)
-			lowestFps = fps;
-		if (highestFps == -1 || fps > highestFps)
-			highestFps = fps;
-		fpsCount++;
-		std::chrono::steady_clock::time_point currentTimePoint = std::chrono::steady_clock::now();
-		if (std::chrono::duration_cast<std::chrono::seconds>(currentTimePoint - fpsStartTime).count() >= 1)
-		{
-			avgFps = fpsCount;
-			lowestFps = -1;
-			highestFps = -1;
-			fpsCount = 0;
-			fpsStartTime = currentTimePoint;
-		}
 
 		waterShader.use();
-		waterShader.setFloat("time", currentFrame);
+		waterShader.setUniform("time", currentTime);
 		outlineShader.use();
-		outlineShader.setFloat("time", currentFrame);
+		outlineShader.setUniform("time", currentTime);
 
 		// Input
-		processInput(window);
+		processInput(window, io);
 
 		// Rendering
 		glEnable(GL_DEPTH_TEST);
@@ -450,7 +441,7 @@ int main(int argc, char *argv[])
 		int localBlockY = blockY - (chunkY * CHUNK_SIZE);
 		int localBlockZ = blockZ - (chunkZ * CHUNK_SIZE);
 
-		Chunk* chunk = Planet::planet->GetChunk(ChunkPos(chunkX, chunkY, chunkZ));
+		Chunk* chunk = Planet::planet->GetChunk(glm::ivec3(chunkX, chunkY, chunkZ));
 		if (chunk != nullptr)
 		{
 			unsigned int blockType = chunk->GetBlockAtPos(
@@ -504,8 +495,8 @@ int main(int argc, char *argv[])
 
 			// Draw ImGui UI
 			ImGui::Begin("Test");
-			ImGui::Text("FPS: %d (Avg: %d, Min: %d, Max: %d)", (int)fps, (int)avgFps, (int)lowestFps, (int)highestFps);
-			ImGui::Text("MS: %f", deltaTime * 100.0f);
+			ImGui::Text("FPS: %d (Avg: %d, Min: %d, Max: %d)", (int)io.Framerate, (int)avgFps, (int)minFps, (int)maxFps);
+			ImGui::Text("MS: %f", io.DeltaTime * 100.0f);
 			if (ImGui::Checkbox("VSYNC", &vsync))
 				glfwSwapInterval(vsync ? 1 : 0);
 			ImGui::Text("Chunks: %d (%d rendered)", Planet::planet->numChunks, Planet::planet->numChunksRendered);
@@ -553,7 +544,7 @@ void framebufferSizeCallback(GLFWwindow* window, int width, int height)
 	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, windowX, windowY, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
 }
 
-void processInput(GLFWwindow* window)
+void processInput(GLFWwindow* window, ImGuiIO& io)
 {
 	// Pause
 	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
@@ -585,20 +576,20 @@ void processInput(GLFWwindow* window)
 	if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
 	{
 		if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
-			camera.ProcessKeyboard(FORWARD_NO_Y, deltaTime);
+			camera.ProcessKeyboard(FORWARD_NO_Y, io.DeltaTime);
 		else
-			camera.ProcessKeyboard(FORWARD, deltaTime);
+			camera.ProcessKeyboard(FORWARD, io.DeltaTime);
 	}
 	if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
-		camera.ProcessKeyboard(BACKWARD, deltaTime);
+		camera.ProcessKeyboard(BACKWARD, io.DeltaTime);
 	if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
-		camera.ProcessKeyboard(LEFT, deltaTime);
+		camera.ProcessKeyboard(LEFT, io.DeltaTime);
 	if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
-		camera.ProcessKeyboard(RIGHT, deltaTime);
+		camera.ProcessKeyboard(RIGHT, io.DeltaTime);
 	if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
-		camera.ProcessKeyboard(UP, deltaTime);
+		camera.ProcessKeyboard(UP, io.DeltaTime);
 	if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
-		camera.ProcessKeyboard(DOWN, deltaTime);
+		camera.ProcessKeyboard(DOWN, io.DeltaTime);
 }
 
 void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
@@ -632,7 +623,7 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
 		int blockX = result.blockX;
 		int blockY = result.blockY;
 		int blockZ = result.blockZ;
-		
+
 		// Choose face to place on
 		if (abs(distX) > abs(distY) && abs(distX) > abs(distZ))
 			blockX += (distX > 0 ? 1 : -1);
@@ -649,7 +640,7 @@ void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
 		int localBlockY = blockY - (chunkY * CHUNK_SIZE);
 		int localBlockZ = blockZ - (chunkZ * CHUNK_SIZE);
 
-		Chunk* chunk = Planet::planet->GetChunk(ChunkPos(chunkX, chunkY, chunkZ));
+		Chunk* chunk = Planet::planet->GetChunk(glm::ivec3(chunkX, chunkY, chunkZ));
 		uint16_t blockToReplace = chunk->GetBlockAtPos(localBlockX, localBlockY, localBlockZ);
 		if (chunk != nullptr && (blockToReplace == 0 || Blocks::blocks[blockToReplace].blockType == Block::LIQUID))
 			chunk->UpdateBlock(localBlockX, localBlockY, localBlockZ, selectedBlock);
@@ -679,4 +670,27 @@ void mouse_callback(GLFWwindow* window, double xpos, double ypos)
 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
 {
 	camera.ProcessMouseScroll(yoffset);
+}
+
+void updateAvgFps(ImGuiIO& io)
+{
+	float fpsSum = 0.0f; // In case all samples are taken so that we only need one cycle
+	for (int i = 0; i < FPS_SAMPLES; i++)
+	{
+		if (fpsSamples[i] != -1)//If this sample has been taken
+		{
+			fpsSum += fpsSamples[i];
+		}
+		else if (fpsSamples[i] == -1 && i != FPS_SAMPLES - 1) // we need a sample here and are not ready for the avg
+		{
+			fpsSamples[i] = io.Framerate;
+			return; // We continue sampleing next call
+		}
+		else if (i == FPS_SAMPLES - 1) // All sample have been taken
+		{
+			fpsSum += io.Framerate;
+			avgFps = fpsSum / FPS_SAMPLES;
+			std::fill(fpsSamples, fpsSamples + FPS_SAMPLES, -1.0f); // Reset samples
+		}
+	}
 }
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/Chunk.cpp b/ScuffedMinecraft/src/Chunk.cpp
index f40bfe5..00c98a2 100644
--- a/ScuffedMinecraft/src/Chunk.cpp
+++ b/ScuffedMinecraft/src/Chunk.cpp
@@ -10,7 +10,7 @@
 #include "Blocks.h"
 #include "WorldGen.h"
 
-Chunk::Chunk(ChunkPos chunkPos, Shader* shader, Shader* waterShader)
+Chunk::Chunk(const glm::ivec3& chunkPos, Shader* shader, Shader* waterShader) // We are not using the passed shaders ??
 	: chunkPos(chunkPos)
 {
 	worldPos = glm::vec3(chunkPos.x * (float)CHUNK_SIZE, chunkPos.y * (float)CHUNK_SIZE, chunkPos.z * (float)CHUNK_SIZE);
diff --git a/ScuffedMinecraft/src/Chunk.h b/ScuffedMinecraft/src/Chunk.h
index 08a4314..6f1d5cf 100644
--- a/ScuffedMinecraft/src/Chunk.h
+++ b/ScuffedMinecraft/src/Chunk.h
@@ -6,13 +6,12 @@
 
 #include "Shader.h"
 #include "Vertex.h"
-#include "ChunkPos.h"
 #include "ChunkData.h"
 
 class Chunk
 {
 public:
-	Chunk(ChunkPos chunkPos, Shader* shader, Shader* waterShader);
+	Chunk(const glm::ivec3& chunkPos, Shader* shader, Shader* waterShader);
 	~Chunk();
 
 	void GenerateChunkMesh();
@@ -30,7 +29,7 @@ public:
 	ChunkData* downData;
 	ChunkData* eastData;
 	ChunkData* westData;
-	ChunkPos chunkPos;
+	glm::ivec3 chunkPos; 
 	bool ready;
 	bool generated;
 
diff --git a/ScuffedMinecraft/src/ChunkData.cpp b/ScuffedMinecraft/src/ChunkData.cpp
index 30895e0..54d045e 100644
--- a/ScuffedMinecraft/src/ChunkData.cpp
+++ b/ScuffedMinecraft/src/ChunkData.cpp
@@ -18,12 +18,12 @@ inline int ChunkData::GetIndex(int x, int y, int z) const
 	return x * CHUNK_SIZE * CHUNK_SIZE + z * CHUNK_SIZE + y;
 }
 
-inline int ChunkData::GetIndex(ChunkPos localBlockPos) const
+inline int ChunkData::GetIndex(const glm::ivec3& localBlockPos) const
 {
 	return localBlockPos.x * CHUNK_SIZE * CHUNK_SIZE + localBlockPos.z * CHUNK_SIZE + localBlockPos.y;
 }
 
-uint16_t ChunkData::GetBlock(ChunkPos blockPos)
+uint16_t ChunkData::GetBlock(const glm::ivec3& blockPos)
 {
 	return data[GetIndex(blockPos)];
 }
diff --git a/ScuffedMinecraft/src/ChunkData.h b/ScuffedMinecraft/src/ChunkData.h
index 1dce469..9c37eb5 100644
--- a/ScuffedMinecraft/src/ChunkData.h
+++ b/ScuffedMinecraft/src/ChunkData.h
@@ -1,8 +1,7 @@
 #pragma once
 
 #include <cstdint>
-
-#include "ChunkPos.h"
+#include <glm/glm.hpp>
 
 struct ChunkData
 {
@@ -12,9 +11,9 @@ struct ChunkData
 	~ChunkData();
 
 	inline int GetIndex(int x, int y, int z) const;
-	inline int GetIndex(ChunkPos localBlockPos) const;
+	inline int GetIndex(const glm::ivec3& localBlockPos) const;
 
-	uint16_t GetBlock(ChunkPos blockPos);
+	uint16_t GetBlock(const glm::ivec3& blockPos);
 	uint16_t GetBlock(int x, int y, int z);
 	void SetBlock(int x, int y, int z, uint16_t block);
 };
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/ChunkPos.cpp b/ScuffedMinecraft/src/ChunkPos.cpp
deleted file mode 100644
index f2930e2..0000000
--- a/ScuffedMinecraft/src/ChunkPos.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "ChunkPos.h"
-
-ChunkPos::ChunkPos()
-	: x(0), y(0), z(0)
-{
-
-}
-
-ChunkPos::ChunkPos(int x, int y, int z)
-	: x(x), y(y), z(z)
-{
-
-}
-
-bool ChunkPos::operator==(const ChunkPos& other) const
-{
-	return other.x == x && other.y == y && other.z == z;
-}
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/ChunkPos.h b/ScuffedMinecraft/src/ChunkPos.h
deleted file mode 100644
index 3358463..0000000
--- a/ScuffedMinecraft/src/ChunkPos.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-struct ChunkPos
-{
-	int x;
-	int y;
-	int z;
-
-	ChunkPos();
-	ChunkPos(int x, int y, int z);
-
-	bool operator==(const ChunkPos& other) const;
-};
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/ChunkPosHash.h b/ScuffedMinecraft/src/ChunkPosHash.h
index 98a5852..c89ecca 100644
--- a/ScuffedMinecraft/src/ChunkPosHash.h
+++ b/ScuffedMinecraft/src/ChunkPosHash.h
@@ -1,9 +1,11 @@
-#include "ChunkPos.h"
+#pragma once
+
 #include <unordered_map>
+#include <glm/glm.hpp>
 
 struct ChunkPosHash
 {
-	std::size_t operator()(const ChunkPos& key) const
+	std::size_t operator()(const glm::ivec3& key) const
 	{
 		std::size_t hx = std::hash<int>()(key.x);
 		std::size_t hy = std::hash<int>()(key.y);
diff --git a/ScuffedMinecraft/src/Physics.cpp b/ScuffedMinecraft/src/Physics.cpp
index 6c020cd..545632e 100644
--- a/ScuffedMinecraft/src/Physics.cpp
+++ b/ScuffedMinecraft/src/Physics.cpp
@@ -6,8 +6,10 @@ Physics::RaycastResult Physics::Raycast(const glm::vec3 startPos, const glm::vec
 {
 	float currentDistance = 0;
 
-	while (currentDistance < maxDistance)
+	std::cout << "Start raycast" << std::endl;
+	while (currentDistance < maxDistance) // This needs optinazion asap I will chnage this to do a dda traversal
 	{
+		std::cout << "Step" << std::endl;
 		currentDistance += Physics::RAY_STEP;
 		if (currentDistance > maxDistance)
 			currentDistance = maxDistance;
@@ -17,7 +19,7 @@ Physics::RaycastResult Physics::Raycast(const glm::vec3 startPos, const glm::vec
 		int chunkX = resultPos.x >= 0 ? resultPos.x / CHUNK_SIZE : resultPos.x / CHUNK_SIZE - 1;
 		int chunkY = resultPos.y >= 0 ? resultPos.y / CHUNK_SIZE : resultPos.y / CHUNK_SIZE - 1;
 		int chunkZ = resultPos.z >= 0 ? resultPos.z / CHUNK_SIZE : resultPos.z / CHUNK_SIZE - 1;
-		Chunk* chunk = Planet::planet->GetChunk(ChunkPos(chunkX, chunkY, chunkZ));
+		Chunk* chunk = Planet::planet->GetChunk(glm::ivec3(chunkX, chunkY, chunkZ));
 		if (chunk == nullptr)
 			continue;
 
diff --git a/ScuffedMinecraft/src/Planet.cpp b/ScuffedMinecraft/src/Planet.cpp
index 1e40bd4..aa3a692 100644
--- a/ScuffedMinecraft/src/Planet.cpp
+++ b/ScuffedMinecraft/src/Planet.cpp
@@ -92,7 +92,7 @@ void Planet::ChunkThreadUpdate()
 	{
 		for (auto it = chunkData.begin(); it != chunkData.end(); )
 		{
-			ChunkPos pos = it->first;
+			glm::ivec3 pos = it->first;
 
 			if (chunks.find(pos) == chunks.end() &&
 				chunks.find({ pos.x + 1, pos.y, pos.z }) == chunks.end() &&
@@ -200,7 +200,7 @@ void Planet::ChunkThreadUpdate()
 			chunkMutex.lock();
 			if (!chunkDataQueue.empty())
 			{
-				ChunkPos chunkPos = chunkDataQueue.front();
+				glm::ivec3 chunkPos = chunkDataQueue.front();
 
 				if (chunkData.find(chunkPos) != chunkData.end())
 				{
@@ -226,7 +226,7 @@ void Planet::ChunkThreadUpdate()
 				if (!chunkQueue.empty())
 				{
 					// Check if chunk exists
-					ChunkPos chunkPos = chunkQueue.front();
+					glm::ivec3 chunkPos = chunkQueue.front();
 					if (chunks.find(chunkPos) != chunks.end())
 					{
 						chunkQueue.pop();
@@ -266,7 +266,7 @@ void Planet::ChunkThreadUpdate()
 
 					// Set top data
 					{
-						ChunkPos topPos(chunkPos.x, chunkPos.y + 1, chunkPos.z);
+						glm::ivec3 topPos(chunkPos.x, chunkPos.y + 1, chunkPos.z);
 						chunkMutex.lock();
 						if (chunkData.find(topPos) == chunkData.end())
 						{
@@ -292,7 +292,7 @@ void Planet::ChunkThreadUpdate()
 
 					// Set bottom data
 					{
-						ChunkPos bottomPos(chunkPos.x, chunkPos.y - 1, chunkPos.z);
+						glm::ivec3 bottomPos(chunkPos.x, chunkPos.y - 1, chunkPos.z);
 						chunkMutex.lock();
 						if (chunkData.find(bottomPos) == chunkData.end())
 						{
@@ -318,7 +318,7 @@ void Planet::ChunkThreadUpdate()
 
 					// Set north data
 					{
-						ChunkPos northPos(chunkPos.x, chunkPos.y, chunkPos.z - 1);
+						glm::ivec3 northPos(chunkPos.x, chunkPos.y, chunkPos.z - 1);
 						chunkMutex.lock();
 						if (chunkData.find(northPos) == chunkData.end())
 						{
@@ -344,7 +344,7 @@ void Planet::ChunkThreadUpdate()
 
 					// Set south data
 					{
-						ChunkPos southPos(chunkPos.x, chunkPos.y, chunkPos.z + 1);
+						glm::ivec3 southPos(chunkPos.x, chunkPos.y, chunkPos.z + 1);
 						chunkMutex.lock();
 						if (chunkData.find(southPos) == chunkData.end())
 						{
@@ -370,7 +370,7 @@ void Planet::ChunkThreadUpdate()
 
 					// Set east data
 					{
-						ChunkPos eastPos(chunkPos.x + 1, chunkPos.y, chunkPos.z);
+						glm::ivec3 eastPos(chunkPos.x + 1, chunkPos.y, chunkPos.z);
 						chunkMutex.lock();
 						if (chunkData.find(eastPos) == chunkData.end())
 						{
@@ -396,7 +396,7 @@ void Planet::ChunkThreadUpdate()
 
 					// Set west data
 					{
-						ChunkPos westPos(chunkPos.x - 1, chunkPos.y, chunkPos.z);
+						glm::ivec3 westPos(chunkPos.x - 1, chunkPos.y, chunkPos.z);
 						chunkMutex.lock();
 						if (chunkData.find(westPos) == chunkData.end())
 						{
@@ -440,7 +440,7 @@ void Planet::ChunkThreadUpdate()
 	}
 }
 
-Chunk* Planet::GetChunk(ChunkPos chunkPos)
+Chunk* Planet::GetChunk(const glm::ivec3& chunkPos)
 {
 	chunkMutex.lock();
 	if (chunks.find(chunkPos) == chunks.end())
diff --git a/ScuffedMinecraft/src/Planet.h b/ScuffedMinecraft/src/Planet.h
index 7394e1b..fde3439 100644
--- a/ScuffedMinecraft/src/Planet.h
+++ b/ScuffedMinecraft/src/Planet.h
@@ -8,7 +8,6 @@
 #include <thread>
 #include <mutex>
 
-#include "ChunkPos.h"
 #include "ChunkData.h"
 #include "Chunk.h"
 #include "ChunkPosHash.h"
@@ -22,10 +21,10 @@ public:
 	Planet(Shader* solidShader, Shader* waterShader, Shader* billboardShader);
 	~Planet();
 
-	ChunkData* GetChunkData(ChunkPos chunkPos);
+	ChunkData* GetChunkData(glm::ivec3& chunkPos);
 	void Update(glm::vec3 cameraPos);
 
-	Chunk* GetChunk(ChunkPos chunkPos);
+	Chunk* GetChunk(const glm::ivec3& chunkPos);
 	void ClearChunkQueue();
 
 private:
@@ -39,11 +38,11 @@ public:
 	int renderHeight = 3;
 
 private:
-	std::unordered_map<ChunkPos, Chunk*, ChunkPosHash> chunks;
-	std::unordered_map<ChunkPos, ChunkData*, ChunkPosHash> chunkData;
-	std::queue<ChunkPos> chunkQueue;
-	std::queue<ChunkPos> chunkDataQueue;
-	std::queue<ChunkPos> chunkDataDeleteQueue;
+	std::unordered_map<glm::ivec3, Chunk*, ChunkPosHash> chunks;
+	std::unordered_map<glm::ivec3, ChunkData*, ChunkPosHash> chunkData;
+	std::queue<glm::ivec3> chunkQueue;
+	std::queue<glm::ivec3> chunkDataQueue;
+	std::queue<glm::ivec3> chunkDataDeleteQueue;
 	unsigned int chunksLoading = 0;
 	int lastCamX = -100, lastCamY = -100, lastCamZ = -100;
 	int camChunkX = -100, camChunkY = -100, camChunkZ = -100;
diff --git a/ScuffedMinecraft/src/Shader.cpp b/ScuffedMinecraft/src/Shader.cpp
index 98c80cf..23eb85f 100644
--- a/ScuffedMinecraft/src/Shader.cpp
+++ b/ScuffedMinecraft/src/Shader.cpp
@@ -102,4 +102,89 @@ void Shader::setInt(const std::string& name, int value) const
 void Shader::setFloat(const std::string& name, float value) const
 {
 	glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
+}
+
+void Shader::setUniform(const std::string& uniformName, int val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform1i(uLoc, val);
+}
+void Shader::setUniform(const std::string& uniformName, unsigned int val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform1i(uLoc, val);
+}
+void Shader::setUniform(const std::string& uniformName, float val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform1f(uLoc, val);
+}
+void Shader::setUniform(const std::string& uniformName, double val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform1f(uLoc, val);
+}
+void Shader::setUniform(const std::string& uniformName, glm::vec2 val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform2f(uLoc, val.x, val.y);
+}
+void Shader::setUniform(const std::string& uniformName, glm::vec3 val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform3f(uLoc, val.x, val.y, val.z);
+}
+void Shader::setUniform(const std::string& uniformName, glm::ivec3 val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniform3f(uLoc, val.x, val.y, val.z);
+}
+void Shader::setUniform(const std::string& uniformName, glm::mat3 val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniformMatrix3fv(uLoc, 1, GL_TRUE, &val[0][0]);
+}
+void Shader::setUniform(const std::string& uniformName, glm::mat4 val)
+{
+	int uLoc = getUniformID(uniformName);
+	if (uLoc < 0)
+		return;
+	glUniformMatrix4fv(uLoc, 1, GL_TRUE, &val[0][0]);
+}
+
+int Shader::getUniformID(const std::string& uniformName) const
+{
+	int uLoc = glGetUniformLocation(ID, uniformName.c_str());
+	if (errorOccurd("While fetching location for uniform with the name " + uniformName))
+		return -1;
+	return uLoc; // Is only callable if no error happens
+}
+
+bool Shader::errorOccurd(const std::string& origin) const
+{
+	GLenum err = glGetError();
+	if (err != GL_NO_ERROR)
+	{
+		std::cerr << origin << " || A OpenGL error occurd with the code " << err;
+		std::cerr << std::endl;
+
+		return true;
+	}
+	return false;
 }
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/Shader.h b/ScuffedMinecraft/src/Shader.h
index e8f9ddb..23a53da 100644
--- a/ScuffedMinecraft/src/Shader.h
+++ b/ScuffedMinecraft/src/Shader.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <string>
+#include <glm/glm.hpp> // Used to pass vec or mat to GPU
 
 class Shader
 {
@@ -16,4 +17,24 @@ public:
 	void setBool(const std::string& name, bool value) const;
 	void setInt(const std::string& name, int value) const;
 	void setFloat(const std::string& name, float value) const;
+
+	// Overloaded uniform setter to avoid type error or overflows
+	void setUniform(const std::string& uniformName, int val);
+	void setUniform(const std::string& uniformName, unsigned int val);
+	void setUniform(const std::string& uniformName, float val);
+	void setUniform(const std::string& uniformName, double val);
+	void setUniform(const std::string& uniformName, glm::vec2 val);
+	void setUniform(const std::string& uniformName, glm::vec3 val);
+	void setUniform(const std::string& uniformName, glm::ivec3 val);
+	void setUniform(const std::string& uniformName, glm::mat3 val);
+	void setUniform(const std::string& uniformName, glm::mat4 val);
+
+	/// Returns -1 if the name is not valid
+	int getUniformID(const std::string& name) const;
+
+private:
+	/// True if a opengl error was reported
+	/// This method should actually be global or something similiar so that everyone can 
+	/// use it but for now this is enough because there isn't even real error handling :)
+	bool errorOccurd(const std::string& origin) const;
 };
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/WorldGen.cpp b/ScuffedMinecraft/src/WorldGen.cpp
index 0702c55..70f85c7 100644
--- a/ScuffedMinecraft/src/WorldGen.cpp
+++ b/ScuffedMinecraft/src/WorldGen.cpp
@@ -7,7 +7,7 @@
 #include "Blocks.h"
 #include "Planet.h"
 
-void WorldGen::GenerateChunkData(ChunkPos chunkPos, uint16_t* chunkData)
+void WorldGen::GenerateChunkData(const glm::ivec3& chunkPos, uint16_t* chunkData)
 {
 	static int chunkSize = CHUNK_SIZE;
 
diff --git a/ScuffedMinecraft/src/WorldGen.h b/ScuffedMinecraft/src/WorldGen.h
index 101ea91..2c5cc0e 100644
--- a/ScuffedMinecraft/src/WorldGen.h
+++ b/ScuffedMinecraft/src/WorldGen.h
@@ -1,12 +1,13 @@
 #pragma once
 
 #include <vector>
+#include <glm/glm.hpp>
+
 #include "NoiseSettings.h"
 #include "SurfaceFeature.h"
 #include "ChunkData.h"
-#include "glm/glm.hpp"
 
 namespace WorldGen
 {
-	void GenerateChunkData(ChunkPos chunkPos, uint16_t* chunkData);
+	void GenerateChunkData(const glm::ivec3& chunkPos, uint16_t* chunkData);
 }
\ No newline at end of file