diff --git a/include/chunk.h b/include/chunk.h
index 5f6e483db1e9d40b7f435d7e0fa8d82fff32f7fe..13a78b8a6ad459e14e26801724e2ba86db99b3c6 100644
--- a/include/chunk.h
+++ b/include/chunk.h
@@ -4,6 +4,7 @@
 #include <cstdint>
 #include <cstdlib>
 #include <string>
+#include <cstdlib>
 #include <iostream>
 
 #include "logger.h"
@@ -30,12 +31,14 @@ class Chunk
 		std::string getRadiationString() const;
 		std::string getAgeString() const;
 
+		int valVisual();
+
 	private:
 		Logger& _logger;
 
-		int _x;
-		int _y;
-		int _z;
+		const int _x;
+		const int _y;
+		const int _z;
 
 		uint16_t wealth;
 		uint16_t weirdness;
@@ -50,6 +53,7 @@ class Chunk
 		int8_t magic;
 
 		void generate_random();
+
 };
 
 #endif // CHUNK_H
diff --git a/include/main.h b/include/main.h
index df761418d694c68ffada308fcddd239d1a4ca59a..efab70116a5388e1c74ba9649b6a8dede035f864 100644
--- a/include/main.h
+++ b/include/main.h
@@ -4,9 +4,15 @@
 #include <iostream>
 #include <cstdint>
 
+enum GenerationMethod
+{
+	Random
+};
+
 #include "save-manager.h"
 #include "game-state.h"
-#include "world-map.h"
+#include "world-hex-2d.h"
+#include "world-map-3d.h"
 #include "chunk.h"
 #include "logger.h"
 
diff --git a/include/world-hex-2d.h b/include/world-hex-2d.h
new file mode 100644
index 0000000000000000000000000000000000000000..c14482d61c7ffb301b2d64071024bb011c72d297
--- /dev/null
+++ b/include/world-hex-2d.h
@@ -0,0 +1,59 @@
+#ifndef WORLD_HEX_2D
+#define WORLD_HEX_2D
+
+#include <unordered_map>
+
+#include "chunk.h"
+#include "logger.h"
+#include "ANSI-colour-codes.h"
+
+#include <string>
+#include <iostream>
+
+
+class WorldHex2D
+{
+	public:
+		WorldHex2D();
+		WorldHex2D( uint8_t radius );
+		WorldHex2D( uint8_t width, uint8_t height, uint8_t depth);
+		~WorldHex2D();
+		void generateWorld();
+
+		Chunk* getChunk( int chunkS, int chunkQ, int chunkR );
+
+		Chunk* getMidChunk();
+		int getMidS();
+		int getMidQ();
+		int getMidR();
+
+		void visualise();
+		void visualiseBlocky();
+		Chunk* showChunk( int s, int q, int r );
+	private:
+		Logger& _logger;
+		std::unordered_map<int, std::unordered_map<int, std::unordered_map<int, Chunk*>>> chunks_;
+		std::string colouriseValue( uint8_t val, int isSolid = 0 );
+
+		uint8_t _width;	// s
+		uint8_t _height;	// q
+		uint8_t _depth;	// r
+		int _minS;	// s
+		int _minQ;	// q
+		int _minR;	// r
+		int _maxS;	// s
+		int _maxQ;	// q
+		int _maxR;	// r
+		
+		std::string visualiseBlock(
+			Chunk* core,
+			Chunk* topLeft,
+			Chunk* topRight,
+			Chunk* right,
+			Chunk* bottomRight,
+			Chunk* bottomLeft,
+			Chunk* left
+		);
+};
+
+#endif // WORLD_HEX_2D
diff --git a/include/world-map.h b/include/world-map-3d.h
similarity index 63%
rename from include/world-map.h
rename to include/world-map-3d.h
index 3f27d9b18dd6dfb7d2bd662310f57c00d493f23e..48df58b9fe5f3af289769bdce21e4bc7472ba27a 100644
--- a/include/world-map.h
+++ b/include/world-map-3d.h
@@ -1,22 +1,17 @@
-#ifndef WORLD_MAP_H
-#define WORLD_MAP_H
+#ifndef WORLD_MAP_3D_H
+#define WORLD_MAP_3D_H
 
 #include <unordered_map>
 
 #include "chunk.h"
 #include "logger.h"
 
-enum GenerationMethod
-{
-	Random
-};
-
-class WorldMap
+class WorldMap3D
 {
 	public:
-		WorldMap();
-		WorldMap( uint8_t width, uint8_t height, uint8_t depth);
-		~WorldMap();
+		WorldMap3D();
+		WorldMap3D( uint8_t width, uint8_t height, uint8_t depth);
+		~WorldMap3D();
 		void generateWorld();
 
 		Chunk* getChunk( int chunkX, int chunkY, int chunkZ );
@@ -29,4 +24,4 @@ class WorldMap
 		uint8_t _depth;	// z
 };
 
-#endif // WORLD_MAP_H
+#endif // WORLD_MAP_3D_H
diff --git a/src/chunk.cpp b/src/chunk.cpp
index a8d1abb181c6266289bb556dcded4e788b8f553f..a6630968c7be03025cb0d087819f1e4e2c593d0f 100644
--- a/src/chunk.cpp
+++ b/src/chunk.cpp
@@ -46,7 +46,8 @@ std::string Chunk::getRadiationString() const { return std::to_string(this->radi
 std::string Chunk::getAgeString() const { return std::to_string(this->age); }
 
 std::string Chunk::getString( ChunkQuery format ) const
-{return "rest";}
+	{return "rest";}
+
 std::string Chunk::getString() const
 {
 	std::string str = "Chunk Details:"
@@ -62,4 +63,10 @@ std::string Chunk::getString() const
 	return str;
 }
 
+int Chunk::valVisual()
+{
+	int val = this->density * 10 / ( 0xFFFF );
+	return val == 0 ? 1 : val;
+}
+
 std::ostream& operator<<( std::ostream& os, const Chunk& obj ) { return os << obj.getString(); }
diff --git a/src/main.cpp b/src/main.cpp
index 098d38178ba09344540860e3ab1039851d4abdfa..953c27a8af6fd4a467eff7747f31f56d008ca352 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -14,11 +14,14 @@ int main() {
 	srand(static_cast<unsigned int>(time(nullptr)));
 	
 	// Genrate a Random chunk
-	WorldMap map(2, 2, 2);
+	WorldHex2D map( 5 );
 	//Chunk* chunk = new Chunk( 0, 0, 0);
 	//std::cout << chunk.getString() << std::endl;
-	Chunk* chunk = map.getChunk(0, 1, 0);
-	std::cout << chunk->getString() << std::endl;
+	// Chunk* chunk = map.getMidChunk();
+	// std::cout << chunk->getString() << std::endl;
+	map.showChunk( 0, 0, 0 );
+	map.showChunk( -2, 1, 1 );
+	map.visualise();
 
 	// Menu Loop
 
diff --git a/src/world-hex-2d.cpp b/src/world-hex-2d.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eb279e5daca4ca423ba9c12e2bffff95b28c32ed
--- /dev/null
+++ b/src/world-hex-2d.cpp
@@ -0,0 +1,207 @@
+#include "world-hex-2d.h"
+WorldHex2D::WorldHex2D() : WorldHex2D( 5 ) {}
+WorldHex2D::WorldHex2D( uint8_t radius )
+	: WorldHex2D(
+			radius % 2 == 0 ? radius + 1 : radius,
+			radius % 2 == 0 ? radius + 1 : radius,
+			radius % 2 == 0 ? radius + 1 : radius
+) {}
+
+WorldHex2D::WorldHex2D( uint8_t width, uint8_t height, uint8_t depth)
+	: _width( width ), _height( height ), _depth( depth ),
+	_logger( Logger::instance() )
+{
+	this->_logger.info( "Creating Hex Map" );
+	this->generateWorld();
+}
+WorldHex2D::~WorldHex2D()
+{
+	this->_logger.info( "Cleaning world" ); 	
+
+	// Clean Chunk Map
+	for( const auto& [keyX, value1] : this->chunks_)
+	{
+		for( const auto& [keyY, value2] : value1)
+		{
+			for( const auto& [keyZ, chunk] : value2)
+				{ delete chunk; }
+		}
+	}
+}
+void WorldHex2D::generateWorld()
+{
+	this->_logger.info( "Generating initial world" );
+	
+	this->_minS = this->_width / -2;	// s
+	this->_minQ = this->_height / -2;	// q
+	this->_minR = this->_depth / -2;	// r
+	this->_maxS = ( this->_width / 2 ) + ( this->_width % 2 == 0 ? 0 : 1 );
+	this->_maxQ = ( this->_height / 2 ) + ( this->_height % 2 == 0 ? 0 : 1 );
+	this->_maxR = ( this->_depth / 2 ) + ( this->_depth % 2 == 0 ? 0 : 1 );
+
+	for( int s = this->_minS; s < this->_maxS; s++ )
+	{
+		for( int q = this->_minQ; q < this->_maxQ; q++ )
+		{
+			for( int r = this->_minR; r < this->_maxR; r++ )
+			{
+				if( s + q + r == 0 )
+				{
+					Chunk* chunk = new Chunk( s, q, r );
+					this->chunks_[s][q][r] = chunk;
+				}
+			}
+		}
+	}
+}
+
+Chunk* WorldHex2D::showChunk( int s, int q, int r )
+{
+	Chunk* chunk = this->getChunk( s, q, r );
+	if( !chunk )
+	{
+		std::cout
+			<< " Chunk Missing: [ "
+			<< s << ", "
+			<< q << ", "
+			<< r << "] "
+			<< std::endl;
+		return nullptr;
+	}
+	
+	// Get Neighbours
+	Chunk * tr = this->getChunk( s+1, q, r-1 );
+	Chunk * xr = this->getChunk( s, q+1, r-1 );
+	Chunk * br = this->getChunk( s-1, q+1, r );
+	Chunk * bl = this->getChunk( s-1, q, r+1 );
+	Chunk * xl = this->getChunk( s, q-1, r+1 );
+	Chunk * tl = this->getChunk( s+1, q-1, r );
+
+	// Visualise
+	std::cout << chunk->getString() << std::endl;
+
+	std::cout << this->visualiseBlock( chunk, tl, tr, xr, br, bl, xl );
+
+	return chunk;
+}
+std::string WorldHex2D::visualiseBlock(
+	Chunk* core,
+	Chunk* topLeft,
+	Chunk* topRight,
+	Chunk* right,
+	Chunk* bottomRight,
+	Chunk* bottomLeft,
+	Chunk* left
+) {
+	int coreVal = core ? core->valVisual() : 0;
+	int tlVal = topLeft ? topLeft->valVisual() : 0;
+	int trVal = topRight ? topRight->valVisual() : 0;
+	int xrVal = right ? right->valVisual() : 0;
+	int brVal = bottomRight ? bottomRight->valVisual() : 0;
+	int blVal = bottomLeft ? bottomLeft->valVisual() : 0;
+	int xlVal = left ? left->valVisual() : 0;
+	std::cout <<
+		" " << this->colouriseValue(tlVal) << " " << this->colouriseValue(trVal) << std::endl
+		<< this->colouriseValue(xlVal) << " " << this->colouriseValue(coreVal, 1) << " " << this->colouriseValue(xrVal) << std::endl
+		<<" " << this->colouriseValue(blVal) << " " << this->colouriseValue(brVal) << std::endl;
+	return "";
+}
+
+Chunk* WorldHex2D::getChunk( int chunkS, int chunkQ, int chunkR )
+{
+	auto chS = chunks_.find( chunkS );
+	if( chS != chunks_.end() )
+	{
+		auto chQ = chS->second.find( chunkQ );
+		if( chQ != chS->second.end() )
+		{
+			auto chR = chQ->second.find( chunkR );
+			if( chR != chQ->second.end() )
+				{ return chR->second; }
+		}
+	}
+
+	return nullptr;
+}
+
+int WorldHex2D::getMidS(){ return this->_width / 2; }
+int WorldHex2D::getMidQ(){ return this->_height / 2; }
+int WorldHex2D::getMidR(){ return this->_depth / 2; }
+Chunk* WorldHex2D::getMidChunk(){
+	return this->getChunk(
+		getMidS(),
+		getMidQ(),
+		getMidR()
+	);
+}
+
+void WorldHex2D::visualise()
+{
+	this->_minS = this->_width / -2;	// s
+	this->_minQ = this->_height / -2;	// q
+	this->_minR = this->_depth / -2;	// r
+	this->_maxS = ( this->_width / 2 ) + ( this->_width % 2 == 0 ? 0 : 1 );
+	this->_maxQ = ( this->_height / 2 ) + ( this->_height % 2 == 0 ? 0 : 1 );
+	this->_maxR = ( this->_depth / 2 ) + ( this->_depth % 2 == 0 ? 0 : 1 );
+
+	for( int s = this->_maxS; s >= this->_minS; s-- )
+	{
+		for( int i = abs(s); i > 0; i-- )
+			{ std::cout << "\u2006"; }
+		// if( s % 2 != 0 ) { std::cout << "\u2006"; } 
+		for( int q = this->_minQ; q < this->_maxQ; q++ )
+		{
+			for( int r = this->_minR; r < this->_maxR; r++ )
+			{
+				if( s + q + r == 0 )
+				{
+					Chunk * chunk = this->getChunk( s,q,r );
+					if( chunk )
+					{
+						std::cout << " " << colouriseValue( chunk->valVisual() );
+//						std::cout<<" \u2b21";
+					} else {
+						std::cout <<" ";
+					}
+					// std::cout<<BLK<<" \u2b21";
+				}
+			}
+		}
+		std::cout<<std::endl;
+	}
+	return;
+}
+
+std::string WorldHex2D::colouriseValue( uint8_t val, int isSolid )
+{
+	std::string valColour  = "";
+	if( val == 0 ) valColour = BLK;
+	else if( val < 2 ) valColour = BLU;
+	else if( val < 4 ) valColour = CYN;
+	else if( val < 6 ) valColour = YEL;
+	else if( val < 8 ) valColour = RED;
+	else valColour = MAG;
+	valColour =  valColour
+		+ (isSolid > 0 ? "\u2b22" : "\u2b21")
+		+ CRESET;
+	return valColour;
+}
+
+void WorldHex2D::visualiseBlocky()
+{
+	for( uint8_t s = 0; s < this->_width; s++ )
+	{
+		for( uint8_t q = 0; q < this->_height; q++ )
+		{
+			for( uint8_t r = 0; r < this->_depth; r++ )
+			{
+				Chunk* chunk = getChunk( s, q, r );
+				if( chunk )
+					{ std::cout << colouriseValue( chunk->valVisual(), 1 ); }
+			}
+			std::cout << std::endl;
+		}
+		std::cout << "#######" << std::endl;
+	}
+	std::cout << "TODO" << std::endl;
+}
diff --git a/src/world-map.cpp b/src/world-map3d.cpp
similarity index 82%
rename from src/world-map.cpp
rename to src/world-map3d.cpp
index d62043c544d454591bfdedbaeba371e85d235822..c34b95ae6b9ae95bcac7c27dbb16e49c509bc9d9 100644
--- a/src/world-map.cpp
+++ b/src/world-map3d.cpp
@@ -1,9 +1,9 @@
-#include "world-map.h"
+#include "world-map-3d.h"
 
-WorldMap::WorldMap()
-	:WorldMap( 5, 5, 5 )
+WorldMap3D::WorldMap3D()
+	:WorldMap3D( 5, 5, 5 )
 {}
-WorldMap::WorldMap(
+WorldMap3D::WorldMap3D(
 		uint8_t width,
 		uint8_t height,
 		uint8_t depth
@@ -14,7 +14,7 @@ WorldMap::WorldMap(
 	this->generateWorld();
 }
 
-WorldMap::~WorldMap(){
+WorldMap3D::~WorldMap3D(){
 	this->_logger.info( "Cleaning world" ); 	
 
 	// Clean Chunk Map
@@ -28,7 +28,7 @@ WorldMap::~WorldMap(){
 	}
 }
 
-Chunk* WorldMap::getChunk(int chunkX, int chunkY, int chunkZ)
+Chunk* WorldMap3D::getChunk(int chunkX, int chunkY, int chunkZ)
 {
 	auto chX = chunks_.find( chunkX );
 	if( chX != chunks_.end() )
@@ -45,7 +45,7 @@ Chunk* WorldMap::getChunk(int chunkX, int chunkY, int chunkZ)
 	return nullptr;
 }
 
-void WorldMap::generateWorld()
+void WorldMap3D::generateWorld()
 {
 	this->_logger.info( "Generating initial world" );
 	for( uint8_t x = 0; x < this->_width; x++ )