diff --git a/game/orders.cpp b/game/orders.cpp
index 836d4e8..80bd284 100644
--- a/game/orders.cpp
+++ b/game/orders.cpp
@@ -6,9 +6,10 @@
 std::string GetStringFromOrder(const COrder& order )
 {
 	std::string ret;
+	ret += "O:";
+	ret += (char)order.order;
+	ret += " U:";
 	ret += std::to_string(order.unit);
-	ret += ORDER_DELIMITER;
-    ret += (char)order.order;
 
 	return ret;
 }
@@ -19,19 +20,18 @@ COrder GetOrderFromString( const std::string& _order )
 	std::string order = _order;
 	COrder ret;
 
-    size_t pos = order.find(ORDER_DELIMITER);
-	if( pos != std::string::npos )
-	{
-		const std::string order_unit = order.substr(0, pos);
+	if( order.substr(0, 2) != "O:" )
+		return COrder();
+	order.erase(0, 2); // Erase the O: prefix
 
-		ret.unit = (unit_id_t)atoi( order_unit.c_str() );
+	ret.order = (order_c)order[0]; // Grab single char oder
+	order.erase(0, 2); // Erase the order and a space
 
-		// Erase everything up to and including the delimiter
-		order.erase(0, pos + 1);
+	if( order.substr(0, 2) != "U:" )
+		return COrder();
+	order.erase(0, 2); // Erase the U: prefix
 
-		// Next single char is the order
-        ret.order = (order_c)order[0];
-	}
+	ret.unit = (unit_id_t)atoi( order.c_str() ); // Grab the unit ID
 
 	return ret;
 }
diff --git a/game/orders.h b/game/orders.h
index 558682f..dde304f 100644
--- a/game/orders.h
+++ b/game/orders.h
@@ -6,8 +6,6 @@
 
 #include "gametypes.h"
 
-#define ORDER_DELIMITER ' '
-
 // Type for all orders ( as a char )
 enum class order_c : char
 {
@@ -47,7 +45,7 @@ inline bool COrder::operator== ( const COrder& rhs ) const
 // Typedef a vector of orders
 typedef std::vector<COrder> COrderVector;
 
-// Order strings stored as simply "[unit id] [order char]"
+// Order strings stored as simply "O:[order char] U:[unit id]"
 // string <--> order conversion functions
 std::string GetStringFromOrder(const COrder& order );
 COrder GetOrderFromString( const std::string& order );
diff --git a/game/unit.cpp b/game/unit.cpp
index 5b52713..9e5591b 100644
--- a/game/unit.cpp
+++ b/game/unit.cpp
@@ -29,6 +29,121 @@ namespace
 	}
 }
 
+// Get a unit from a visual
+CUnit GetUnitFromVis( unitVis_c vis )
+{
+    CUnit unit;
+    unit.setFromVisual(vis);
+    return unit;
+}
+
+// Get a string descriptor of a unit
+// "U:[unit_id] T:[team_id] P:[player_id] V:[unit_vis] D:[dir] POS:[pos.x],[pos.y]"
+std::string GetStringFromUnit(const CUnit& unit )
+{
+    std::string ret;
+    ret += "U:";
+    ret += std::to_string(unit.getID());
+    ret += " T:";
+    ret += std::to_string((int)unit.getTeam());
+    ret += " P:";
+    ret += std::to_string(unit.getPlayer());
+    ret += " V:";
+    ret += (char)unit.getVisual();
+    ret += " D:";
+    ret += (char)unit.getDir();
+    ret += " POS:";
+    ret += std::to_string(unit.getPos().x);
+    ret += ",";
+    ret += std::to_string(unit.getPos().y);
+
+    return ret;
+}
+
+// Get a unit from a string descriptor
+// "U:[unit_id] T:[team_id] P:[player_id] V:[unit_vis] D:[dir] POS:[pos.x],[pos.y]"
+CUnit GetUnitFromString(const std::string& _unit )
+{
+    std::string unit = _unit;
+    CUnit ret;
+    size_t pos;
+
+    // UNIT ID
+    if( unit.substr(0, 2) != "U:" )
+        return CUnit();
+    unit.erase(0, 2); // Erase the U: prefix
+
+    pos = unit.find(' ');
+    if( pos == std::string::npos )
+        return CUnit();
+
+    const unit_id_t id = (unit_id_t)atoi( unit.substr(0,pos).c_str() ); // Grab the ID
+    ret.setIDForced( id ); // Force set the ID
+    unit.erase(0, pos+1); // Erase the ID and a space
+
+    // TEAM
+    if( unit.substr(0, 2) != "T:" )
+        return CUnit();
+    unit.erase(0, 2); // Erase the T: prefix
+
+    pos = unit.find(' ');
+    if( pos == std::string::npos )
+        return CUnit();
+
+    const Team team = (Team)atoi( unit.substr(0,pos).c_str() ); // Grab the ID
+    ret.setTeam( team ); // Force set the ID
+    unit.erase(0, pos+1); // Erase the team and a space
+
+    // PLAYER
+    if( unit.substr(0, 2) != "P:" )
+        return CUnit();
+    unit.erase(0, 2); // Erase the P: prefix
+
+    pos = unit.find(' ');
+    if( pos == std::string::npos )
+        return CUnit();
+
+    const player_id_t player = (player_id_t)atoi( unit.substr(0,pos).c_str() ); // Grab the ID
+    ret.setPlayer( player ); // Force set the ID
+    unit.erase(0, pos+1); // Erase the player and a space
+
+    // VISUAL
+    if( unit.substr(0, 2) != "V:" )
+        return CUnit();
+    unit.erase(0, 2); // Erase the W: prefix
+
+    unitVis_c vis = unit[0];
+    ret.setVisual(vis);
+    unit.erase(0, 2); // Erase the vis and a space
+
+    // DIRECTION
+    if( unit.substr(0, 2) != "D:" )
+        return CUnit();
+    unit.erase(0, 2); // Erase the D: prefix
+
+    dir_t dir = (dir_t)unit[0];
+    ret.setDir(dir);
+    unit.erase(0, 2); // Erase the ID and a space
+
+    // POSITION
+    if( unit.substr(0, 4) != "POS:" )
+        return CUnit();
+    unit.erase(0, 4); // Erase the Pos: prefix
+
+    pos = unit.find(',');
+    if( pos == std::string::npos )
+        return CUnit();
+
+    uvector2 upos;
+    upos.x = (ucoord_t)atoi( unit.substr(0,pos).c_str() ); // Grab the x
+    unit.erase(0, pos+1); // Erase the x and the comma
+
+    upos.y = (ucoord_t)atoi( unit.c_str() ); // Grab the y from what's left
+    ret.setPos( upos ); //Set the position
+
+    return ret;
+}
+
 // Plain constructor
 CUnit::CUnit()
 : unit_id 	( get_unique_unit_id() )
@@ -66,12 +181,15 @@ CUnit& CUnit::operator=(CUnit&& unit)
     return *this;
 }
 
-// Get a unit from a visual
-CUnit CUnit::getUnitFromVis( unitVis_c vis )
+// Equals operator
+bool CUnit::operator==(const CUnit& rhs)
 {
-	CUnit unit;
-	unit.setFromVisual(vis);
-    return unit;
+    return (unit_id == rhs.unit_id)
+        && (team_id == rhs.team_id)
+        && (player_id == rhs.player_id)
+        && (unit_vis == rhs.unit_vis)
+        && (dir == rhs.dir)
+        && (pos == rhs.pos);
 }
 
 // Update the visual representation of the unit
diff --git a/game/unit.h b/game/unit.h
index 4c6d13f..a6ef88d 100644
--- a/game/unit.h
+++ b/game/unit.h
@@ -15,16 +15,19 @@ public:
     // Constructor
 	CUnit();
 
-    // Move constructor and move asignement. CUnit cannot be copied
+    // Move constructor and move assignment. CUnit cannot be copied
     CUnit(CUnit&& unit);
     CUnit& operator=(CUnit&& unit);
 
+	bool operator==(const CUnit& rhs);
+	bool operator!=(const CUnit& rhs) { return !(*this == rhs); }
+
     // Default dtor
 	~CUnit() = default;
 
     // Getters for all the members
 	inline const unit_id_t& 	getID() const 		{ return unit_id; }
-	inline const Team & 	getTeam() const 	{ return team_id; }
+	inline const Team & 		getTeam() const 	{ return team_id; }
 	inline const player_id_t& 	getPlayer() const 	{ return player_id; }
 	inline const unitVis_c&		getVisual() const 	{ return unit_vis; }
     inline const dir_t&         getDir() const      { return dir; }
@@ -39,6 +42,9 @@ public:
 	inline const uvector2& 		getPos() const 						{ return pos; }
 	inline void 				setPos(const uvector2& v)  			{ pos = v; }
 
+
+	inline const unit_id_t& 	setIDForced(const unit_id_t& v)  	{ return (unit_id = v); }
+
     // Get the co-ordinate infront of the unit
     uvector2 getInFront() const;
 
@@ -48,9 +54,6 @@ public:
 	// Set a unit based solely on it's visual
 	bool 		setFromVisual( const unitVis_c& vis);
 
-	// Factory function for creating units from a visual
-    static CUnit getUnitFromVis( unitVis_c vis );
-
     // Orientation methods
     dir_t turnLeft();
     dir_t turnRight();
@@ -92,4 +95,14 @@ inline bool CUnit::valid() const
 		&& (unit_vis 	!= unitVis_invalid);
 }
 
+
+// Factory function for creating units from a visual
+CUnit GetUnitFromVis( unitVis_c vis );
+
+// Units strings stored as
+// "U:[unit_id] T:[team_id] P:[player_id] V:[unit_vis] D:[dir] POS:[pos.x],[pos.y]"
+// Unit <--> string conversion functions
+std::string GetStringFromUnit(const CUnit& unit );
+CUnit GetUnitFromString(const std::string& unit );
+
 #endif //_UNIT_H_
diff --git a/maths/vector2.h b/maths/vector2.h
index 6552807..ee36d5d 100644
--- a/maths/vector2.h
+++ b/maths/vector2.h
@@ -7,6 +7,7 @@ struct uvector2;
 
 struct vector2
 {
+    vector2() : x (0), y (0) {}
     vector2( coord_t _x, coord_t _y )
     : x(_x)
     , y(_y)
@@ -32,6 +33,7 @@ struct vector2
 
 struct uvector2
 {
+    uvector2() : x (0), y (0) {}
     uvector2( ucoord_t _x, ucoord_t _y )
     : x(_x)
     , y(_y)
diff --git a/test/test.cpp b/test/test.cpp
index 1306d1e..160f6bb 100644
--- a/test/test.cpp
+++ b/test/test.cpp
@@ -22,9 +22,35 @@ const char* tests()
 			 return "Unit IDs the same";
 	}
 
+    // Test basic invalid unit conversion
+    {
+        CUnit unit1;
+
+        std::string unit1Desc = GetStringFromUnit(unit1);
+        CUnit unit2 = GetUnitFromString(unit1Desc);
+
+        if ( unit1 != unit2 )
+            return "Failed to convert an empty unit to string and back";
+    }
+
+    // Test custom unit conversion
+    {
+        CUnit unit1;
+        unit1.setFromVisual('v');
+        unit1.setPlayer(0);
+        unit1.setTeam(Team::Green);
+        unit1.setPos( uvector2(5,10) );
+
+        std::string unit1Desc = GetStringFromUnit(unit1);
+        CUnit unit2 = GetUnitFromString(unit1Desc);
+
+        if ( unit1 != unit2 )
+            return "Failed to convert custom unit to string and back";
+    }
+
     // Test if we can successfully create a unit from a visual
 	{
-		CUnit unit = CUnit::getUnitFromVis('v');
+		CUnit unit = GetUnitFromVis('v');
 		if( unit.getVisual() != 'v' )
 			return "failed to properly create V unit with factory";
 	}
@@ -56,7 +82,7 @@ const char* tests()
         CTTRTSGame game( 5, 5 );
 
         {
-            CUnit unit = CUnit::getUnitFromVis('^');
+            CUnit unit = GetUnitFromVis('^');
             unit.setPos( {2,2} );
             unit.setPlayer(0);
             unit.setTeam(Team::Red);
@@ -65,7 +91,7 @@ const char* tests()
         }
 
         {
-            CUnit unit = CUnit::getUnitFromVis('^');
+            CUnit unit = GetUnitFromVis('^');
             unit.setPos( {2,2} );
             unit.setPlayer(0);
             unit.setTeam(Team::Red);
@@ -82,7 +108,7 @@ const char* tests()
     {
         CTTRTSGame game( 5, 5 );
 
-        CUnit unit = CUnit::getUnitFromVis('>');
+        CUnit unit = GetUnitFromVis('>');
         const unit_id_t id = unit.getID();
         COrder order;
 
@@ -113,7 +139,7 @@ const char* tests()
 
         unit_id_t id;
         {
-            CUnit unit = CUnit::getUnitFromVis('>');
+            CUnit unit = GetUnitFromVis('>');
             id = unit.getID();
             COrder order;
 
@@ -131,7 +157,7 @@ const char* tests()
                 return "Game failed to issue valid order";
         }
         {
-            CUnit unit = CUnit::getUnitFromVis('<');
+            CUnit unit = GetUnitFromVis('<');
 
             unit.setPos( {1,0} );
             unit.setPlayer(2);