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 51a7e45..226871d 100644
--- a/ScuffedMinecraft/src/Application.cpp
+++ b/ScuffedMinecraft/src/Application.cpp
@@ -441,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(
@@ -640,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);
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..e0528c1 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; // why do we have 2 position with the same byte layout and why is worldpos not a int type
 	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/KeyInput.cpp b/ScuffedMinecraft/src/KeyInput.cpp
new file mode 100644
index 0000000..5451de0
--- /dev/null
+++ b/ScuffedMinecraft/src/KeyInput.cpp
@@ -0,0 +1,68 @@
+#include "KeyInput.h"
+
+#include <algorithm>
+
+std::vector<KeyInput*> KeyInput::instances;
+glm::vec2 KeyInput::cursorPos;
+glm::vec2 KeyInput::mouseScroll;
+
+KeyInput::KeyInput(const std::vector<int>& keysToMonitor)
+{
+    for (int key : keysToMonitor)
+        keys[key] = false;
+    // Add this instance to the list of instances
+    KeyInput::instances.push_back(this);
+}
+
+KeyInput::~KeyInput()
+{
+    // Remove this instance from the list of instances
+    instances.erase(std::remove(instances.begin(), instances.end(), this), instances.end());
+}
+
+bool KeyInput::isKeyDown(int key)
+{
+    std::map<int, bool>::iterator it = keys.find(key);
+    if (it != keys.end())
+        return keys[key];
+}
+
+void KeyInput::setKeyDown(int key, bool isDown)
+{
+    std::map<int, bool>::iterator it = keys.find(key);
+    if (it != keys.end())
+        keys[key] = isDown;
+}
+
+void KeyInput::setupCallbacks(GLFWwindow*& window)
+{
+    glfwSetKeyCallback(window, KeyInput::keyCallback);
+    glfwSetCursorPosCallback(window, KeyInput::cursorPosCallback);
+    glfwSetMouseButtonCallback(window, KeyInput::mouseButtonCallBack);
+}
+
+void KeyInput::keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
+{
+    // Send key event to all KeyInput instances
+    for (KeyInput* keyInput : instances)
+        keyInput->setKeyDown(key, action != GLFW_RELEASE);
+}
+
+void KeyInput::mouseButtonCallBack(GLFWwindow* window, int button, int action, int mods)
+{
+    // Send key event to all KeyInput instances
+    for (KeyInput* keyInput : instances)
+        keyInput->setKeyDown(button, action != GLFW_RELEASE);
+}
+
+void KeyInput::cursorPosCallback(GLFWwindow* window, double xpos, double ypos)
+{
+    cursorPos.x = xpos;
+    cursorPos.y = ypos;
+}
+
+void KeyInput::scrollCallback(GLFWwindow* window, double xoffset, double yoffset) 
+{
+    mouseScroll.x = xoffset;
+    mouseScroll.y = yoffset;
+}
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/KeyInput.h b/ScuffedMinecraft/src/KeyInput.h
new file mode 100644
index 0000000..f6ff6b0
--- /dev/null
+++ b/ScuffedMinecraft/src/KeyInput.h
@@ -0,0 +1,32 @@
+#pragma once
+#include <glm/glm.hpp>
+#include <GLFW/glfw3.h>
+#include <map>
+#include <vector>
+
+// The naming conventions of this project do not seems to be 100% clear 
+// but I guess that member functions start with a uppercase letters and 
+// functions with lowercase
+class KeyInput
+{
+private:
+    std::map<int, bool> keys;
+    static std::vector<KeyInput*> instances;
+public:
+    static glm::vec2 cursorPos;
+    static glm::vec2 mouseScroll;
+public:
+    /// This takes in a vector containing all keys that should be monitord by this instance
+    KeyInput(const std::vector<int>& keysToMonitor);
+    ~KeyInput();
+    bool isKeyDown(int key);
+    // This function should only be called once after OpenGL and glfw are all set up and ready to go 
+    static void setupCallbacks(GLFWwindow*& window);
+
+private:
+    void setKeyDown(int key, bool isDown);
+    static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
+    static void mouseButtonCallBack(GLFWwindow* window, int button, int action, int mods);
+    static void cursorPosCallback(GLFWwindow* window, double xpos, double ypos);
+    static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset);
+};
\ No newline at end of file
diff --git a/ScuffedMinecraft/src/Physics.cpp b/ScuffedMinecraft/src/Physics.cpp
index 6c020cd..118843a 100644
--- a/ScuffedMinecraft/src/Physics.cpp
+++ b/ScuffedMinecraft/src/Physics.cpp
@@ -17,7 +17,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/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..4fca6c1 100644
--- a/ScuffedMinecraft/src/WorldGen.h
+++ b/ScuffedMinecraft/src/WorldGen.h
@@ -8,5 +8,5 @@
 
 namespace WorldGen
 {
-	void GenerateChunkData(ChunkPos chunkPos, uint16_t* chunkData);
+	void GenerateChunkData(const glm::ivec3& chunkPos, uint16_t* chunkData);
 }
\ No newline at end of file