diff --git a/Source/DasherVR/Private/SDasherWidget.cpp b/Source/DasherVR/Private/SDasherWidget.cpp
index dce12ea734af1ea5ef1519695bc24b95f8128ae9..4cb2b611cefa424fb8ede6bbe97bcd66afa5f513 100644
--- a/Source/DasherVR/Private/SDasherWidget.cpp
+++ b/Source/DasherVR/Private/SDasherWidget.cpp
@@ -49,13 +49,14 @@ FReply SDasherWidget::HandleMouseMoveEvent(const FGeometry& Geometry, const FPoi
 
         if(URWTHVRUtilities::IsRoomMountedMode())
 	    {
-		    FDisplayClusterClusterEventJson ClusterEvent;
-	        ClusterEvent.Category = "Dasher";
-	        ClusterEvent.Type = "Input";
-	        ClusterEvent.Name = "MouseMove";
-            ClusterEvent.Parameters.Add("X", FString::SanitizeFloat(CursorPosition.X));
-            ClusterEvent.Parameters.Add("Y", FString::SanitizeFloat(CursorPosition.Y));
-		    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false);
+            FDisplayClusterClusterEventBinary ClusterEvent;
+	        ClusterEvent.EventId = DasherEventID;
+	        ClusterEvent.EventData.Reserve(sizeof(CursorPosition.X) + sizeof(CursorPosition.Y) + 1);
+	        ClusterEvent.EventData[0] = static_cast<uint8>(DasherEventType::Input_MouseMove);
+	        FMemory::Memcpy(&ClusterEvent.EventData[1], &CursorPosition.X, sizeof(CursorPosition.X));
+	        FMemory::Memcpy(&ClusterEvent.EventData[1] + sizeof(CursorPosition.X), &CursorPosition.Y, sizeof(CursorPosition.Y));
+		    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventBinary(ClusterEvent, false);
+
 	        return FReply::Handled().ReleaseMouseLock();
 	    }
     }
@@ -68,11 +69,12 @@ FReply SDasherWidget::HandleMouseDownEvent(const FGeometry& Geometry, const FPoi
     {
         if(URWTHVRUtilities::IsRoomMountedMode())
 	    {
-		    FDisplayClusterClusterEventJson ClusterEvent;
-	        ClusterEvent.Category = "Dasher";
-	        ClusterEvent.Type = "Input";
-	        ClusterEvent.Name = "MouseDown";
-		    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false);
+            FDisplayClusterClusterEventBinary ClusterEvent;
+	        ClusterEvent.EventId = DasherEventID;
+	        ClusterEvent.EventData.Reserve(1);
+	        ClusterEvent.EventData[0] = static_cast<uint8>(DasherEventType::Input_MouseDown);
+		    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventBinary(ClusterEvent, false);
+
 	        return FReply::Handled().ReleaseMouseLock();
 	    }
 
@@ -91,11 +93,11 @@ FReply SDasherWidget::HandleMouseUpEvent(const FGeometry& Geometry, const FPoint
 {
     if(URWTHVRUtilities::IsRoomMountedMode())
     {
-	    FDisplayClusterClusterEventJson ClusterEvent;
-        ClusterEvent.Category = "Dasher";
-        ClusterEvent.Type = "Input";
-        ClusterEvent.Name = "MouseUp";
-	    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false);
+	    FDisplayClusterClusterEventBinary ClusterEvent;
+        ClusterEvent.EventId = DasherEventID;
+        ClusterEvent.EventData.Reserve(1);
+        ClusterEvent.EventData[0] = static_cast<uint8>(DasherEventType::Input_MouseUp);
+	    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventBinary(ClusterEvent, false);
         return FReply::Handled().ReleaseMouseLock();
     }
 
@@ -117,11 +119,11 @@ FReply SDasherWidget::HandleMouseDoubleClickEvent(const FGeometry& Geometry, con
     {
 	    if(URWTHVRUtilities::IsRoomMountedMode())
 	    {
-		    FDisplayClusterClusterEventJson ClusterEvent;
-	        ClusterEvent.Category = "Dasher";
-	        ClusterEvent.Type = "Input";
-	        ClusterEvent.Name = "MouseDown";
-		    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false);
+		    FDisplayClusterClusterEventBinary ClusterEvent;
+	        ClusterEvent.EventId = DasherEventID;
+	        ClusterEvent.EventData.Reserve(1);
+	        ClusterEvent.EventData[0] = static_cast<uint8>(DasherEventType::Input_MouseDown);
+		    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventBinary(ClusterEvent, false);
 	        return FReply::Handled().ReleaseMouseLock();
 	    }
 
@@ -152,32 +154,30 @@ bool SDasherWidget::GetScreenCoords(screenint& iX, screenint& iY, Dasher::CDashe
     return true;
 }
 
-void SDasherWidget::HandleClusterEvent(const FDisplayClusterClusterEventJson& Event)
+void SDasherWidget::HandleClusterEvent(const FDisplayClusterClusterEventBinary& Event)
 {
-    if(Event.Category != "Dasher") return;
-    if(Event.Type == "Input")
+    if(Event.EventId != DasherEventID) return;
+
+    switch(static_cast<DasherEventType>(Event.EventData[0]))
     {
-	    if(Event.Name == "MouseUp")
-	    {
-			DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), Dasher::Keys::Primary_Input);
-			MouseUpListeners.ExecuteIfBound();   
-	    } else
-        if(Event.Name == "MouseDown")
-	    {
-		    DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), Dasher::Keys::Primary_Input);
-			MouseDownListeners.ExecuteIfBound();
-	    } else
-        if(Event.Name == "MouseMove")
-	    {
-            CursorPosition.X = FCString::Atod(*Event.Parameters["X"]);
-            CursorPosition.Y = FCString::Atod(*Event.Parameters["Y"]);
-	    }
-    } else
-	if(Event.Type == "Tick")
-	{
-		double currentTime = FCString::Atod(*Event.Parameters["Time"]);
+    case DasherEventType::Input_MouseDown:
+        DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), Dasher::Keys::Primary_Input);
+		MouseDownListeners.ExecuteIfBound();
+	    break;
+    case DasherEventType::Input_MouseUp:
+        DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), Dasher::Keys::Primary_Input);
+		MouseUpListeners.ExecuteIfBound();   
+	    break;
+    case DasherEventType::Input_MouseMove:
+        FMemory::Memcpy(&CursorPosition.X, &Event.EventData[1], sizeof(CursorPosition.X));
+        FMemory::Memcpy(&CursorPosition.Y, &Event.EventData[1] + sizeof(CursorPosition.X), sizeof(CursorPosition.Y));
+	    break;
+    case DasherEventType::Tick:
+        double currentTime = 0;
+    	FMemory::Memcpy(&currentTime, &Event.EventData[1], sizeof(currentTime));
         DasherMainInterface->Tick(static_cast<unsigned long>(currentTime * 1000.0));
-	}
+	    break;
+    }
 }
 
 void SDasherWidget::InputVector(const FVector2D InputVector)
@@ -230,11 +230,11 @@ void SDasherWidget::Construct(const FArguments& InArgs)
 
     // Bind the cluster events that manage the door state.
     IDisplayClusterClusterManager* ClusterManager = IDisplayCluster::Get().GetClusterMgr();
-    if (ClusterManager && !ClusterEventListener.IsBound())
+    if (URWTHVRUtilities::IsRoomMountedMode() && ClusterManager && !ClusterEventListener.IsBound())
     {
         ClusterEventListener =
-            FOnClusterEventJsonListener::CreateSP(this, &SDasherWidget::HandleClusterEvent);
-        ClusterManager->AddClusterEventJsonListener(ClusterEventListener);
+            FOnClusterEventBinaryListener::CreateSP(this, &SDasherWidget::HandleClusterEvent);
+        ClusterManager->AddClusterEventBinaryListener(ClusterEventListener);
     }
 
     if (URWTHVRUtilities::IsPrimaryNode())
@@ -300,10 +300,10 @@ int32 SDasherWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
 
 //The tick function, we tick dasher in it and update the screen size for dasher
 void SDasherWidget::Tick(const FGeometry& AllotedGeometry, const double InCurrentTime, const float InDeltaTime) {
-    SCompoundWidget::Tick(AllotedGeometry, InCurrentTime, InDeltaTime);
-
     //don't tick in the editor
-    if (!IsEditor && !InputPaused) return;
+    if (IsEditor || InputPaused) return;
+
+    SCompoundWidget::Tick(AllotedGeometry, InCurrentTime, InDeltaTime);
 
     if(!URWTHVRUtilities::IsRoomMountedMode()){
         DasherMainInterface->Tick(static_cast<unsigned long>(InCurrentTime * 1000.0)); //we need to provide ticks in milliseconds
@@ -311,11 +311,12 @@ void SDasherWidget::Tick(const FGeometry& AllotedGeometry, const double InCurren
 	else
     if(URWTHVRUtilities::IsPrimaryNode())
     {
-        FDisplayClusterClusterEventJson ClusterEvent;
-        ClusterEvent.Category = "Dasher";
-        ClusterEvent.Type = "Tick";
-        ClusterEvent.Parameters.Add("Time", FString::SanitizeFloat(InCurrentTime));
-	    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false);
+        FDisplayClusterClusterEventBinary ClusterEvent;
+        ClusterEvent.EventId = DasherEventID;
+        ClusterEvent.EventData.Reserve(sizeof(InCurrentTime) + 1);
+        ClusterEvent.EventData[0] = static_cast<uint8>(DasherEventType::Tick);
+        FMemory::Memcpy(&ClusterEvent.EventData[1], &InCurrentTime, sizeof(InCurrentTime));
+	    IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventBinary(ClusterEvent, false);
     }
 
     //This probably doesn't have to be done every tick, but it does not seem to have a huge hit on performance
diff --git a/Source/DasherVR/Public/SDasherWidget.h b/Source/DasherVR/Public/SDasherWidget.h
index 4b5bd278e1d74cf42d99aa57be817c5ac8d818cb..a806432abbf1ef78e4ce528c311b0f3c065b309a 100644
--- a/Source/DasherVR/Public/SDasherWidget.h
+++ b/Source/DasherVR/Public/SDasherWidget.h
@@ -21,6 +21,14 @@ enum class GeometryType : uint8
 	PolyLine = 2
 };
 
+enum class DasherEventType : uint8
+{
+	Input_MouseDown = 1,
+	Input_MouseUp = 2,
+	Input_MouseMove = 3,
+	Tick
+};
+
 struct DasherDrawGeometry
 {
 	GeometryType Type;
@@ -124,7 +132,7 @@ public:
 
 	virtual bool GetScreenCoords(screenint& iX, screenint& iY, Dasher::CDasherView* pView) override;
 
-	void HandleClusterEvent(const FDisplayClusterClusterEventJson& Event);
+	void HandleClusterEvent(const FDisplayClusterClusterEventBinary& Event);
 
 	void InputVector(FVector2D InputVector);
 	void InputButton(bool Pressed);
@@ -166,7 +174,8 @@ private:
 	TSharedPtr<FSlateFontMeasure> FontMeasureService;
 
 	//CAVE Sync
-	FOnClusterEventJsonListener ClusterEventListener;
+	FOnClusterEventBinaryListener ClusterEventListener;
+	inline static int32 DasherEventID = -424242;
 
 protected:
 	// stores color information 
diff --git a/Source/Thirdparty/Dasher/DasherCore b/Source/Thirdparty/Dasher/DasherCore
index f6211ff1ad2e6aaf3a0ecf7ecb58aec610893b52..cc15dde0fd16e08d43578ee861770049d9cf3575 160000
--- a/Source/Thirdparty/Dasher/DasherCore
+++ b/Source/Thirdparty/Dasher/DasherCore
@@ -1 +1 @@
-Subproject commit f6211ff1ad2e6aaf3a0ecf7ecb58aec610893b52
+Subproject commit cc15dde0fd16e08d43578ee861770049d9cf3575
diff --git a/Source/Thirdparty/Dasher/Lib/DasherCore.a b/Source/Thirdparty/Dasher/Lib/DasherCore.a
index 77d401c435ff6fd6b30cf5dced2db7796791c8d9..07b54651cd309089dcfdcdd9827ae3f0a41af66c 100644
Binary files a/Source/Thirdparty/Dasher/Lib/DasherCore.a and b/Source/Thirdparty/Dasher/Lib/DasherCore.a differ
diff --git a/Source/Thirdparty/Dasher/Lib/DasherCore.lib b/Source/Thirdparty/Dasher/Lib/DasherCore.lib
index f6fcc0b262a35b3beb1cd44e1d76c564867c54ab..aa79e6914e1caf8fe7a53877ae4b656f0f48e526 100644
--- a/Source/Thirdparty/Dasher/Lib/DasherCore.lib
+++ b/Source/Thirdparty/Dasher/Lib/DasherCore.lib
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:aabffff7bea2fe1a696c01b35344a381f1da6075928bc3dbee9131143eef7d66
-size 29696466
+oid sha256:ab3df577eca33109138372ab5a07ab69018f91e4d3a8ea931d16a38ac2eac9c8
+size 29906720
diff --git a/Source/Thirdparty/Dasher/Lib/DasherCore.pdb b/Source/Thirdparty/Dasher/Lib/DasherCore.pdb
index 70bf6b88afa9394bf1c2a60e6895c731a985b585..c41df9890c22d2dfb12afb7e145d213f8fbc314e 100644
Binary files a/Source/Thirdparty/Dasher/Lib/DasherCore.pdb and b/Source/Thirdparty/Dasher/Lib/DasherCore.pdb differ
diff --git a/Source/Thirdparty/Dasher/Lib/pugixml.lib b/Source/Thirdparty/Dasher/Lib/pugixml.lib
index cc5f076671ff70b42d2c22427a759760c21d7f69..80f1c8b20aaccaed84c00961ab254537f3d15605 100644
--- a/Source/Thirdparty/Dasher/Lib/pugixml.lib
+++ b/Source/Thirdparty/Dasher/Lib/pugixml.lib
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:50b65a51cb2f9725e9aa50ec22d9b96566400dd18c424bf28bdb98a6bdc63782
-size 1492990
+oid sha256:f7ec6ae4c3797a922ed90d820a9bac4f887f9418bd5d1bf569185c4db8feb3b3
+size 1502086
diff --git a/Source/Thirdparty/Dasher/Lib/pugixml.pdb b/Source/Thirdparty/Dasher/Lib/pugixml.pdb
index ce063a7660e3e0bfde4796129e03c37b0abd4082..60a6731a7b9f585455423a8dbf6a29f57dd3f62e 100644
Binary files a/Source/Thirdparty/Dasher/Lib/pugixml.pdb and b/Source/Thirdparty/Dasher/Lib/pugixml.pdb differ