diff --git a/src/gameoflife.cpp b/src/gameoflife.cpp
index 421183832c6c487205d1e405c7512af1171de494..fde43972b1d44103462320eeb9b5f4785a6960c7 100644
--- a/src/gameoflife.cpp
+++ b/src/gameoflife.cpp
@@ -36,6 +36,7 @@ void setupGameOfLife()
   {
     addGlider(random(SCREEN_HEIGHT), random(SCREEN_WIDTH), g);
   }
+  logLine("Starting Game " + String(gameEra));
 }
 
 void createRandomMatrix(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH])
diff --git a/src/network.cpp b/src/network.cpp
index c080dba5f38ed6e7cb96d79df201534c9775037c..fc1d8b13576222c4e42a7a924b441d1f073abf14 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -11,6 +11,8 @@ AsyncWebSocket ws("/ws");
 ESPTelnet telnet;
 IPAddress ip;
 
+int otaProgress = 0;
+
 void setupNetwork()
 {
   setupWifi();
@@ -53,9 +55,6 @@ void setupOTA()
   ArduinoOTA.onStart([]()
                      {
                       runGame = false;
-                      if (ArduinoOTA.getCommand() != U_FLASH) {
-                        LittleFS.end();
-                      }
                       ws.enable(false);
                       ws.textAll("OTA Update Started");
                       ws.closeAll();
@@ -68,12 +67,16 @@ void setupOTA()
                     clearDisplay(); });
   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
                         {
-    char msg[10];
-    sprintf(msg, "OTA:%3d%%", (progress/(total/100)));
-    showMessage(msg);
-    logLine("OTA: ", false);
-    logLine((String)(progress/(total/100)), false);
-    logLine("%"); });
+                          int percent = ceil(progress/(total/100));
+                          if (percent > otaProgress) {
+                            char msg[10];
+                            sprintf(msg, "OTA:%3d%%", percent);
+                            showMessage(msg);
+                            logLine("OTA: ", false);
+                            logLine((String)percent, false);
+                            logLine("%");
+                            otaProgress = percent;
+                          } });
   ArduinoOTA.onError([](ota_error_t error)
                      {
     if(error == OTA_AUTH_ERROR) logLine("OTA Auth Failed");
@@ -122,8 +125,7 @@ void setupWebserver()
 void networkLoop()
 {
   ArduinoOTA.handle();
-  if (runGame)
-    telnet.loop();
+  telnet.loop();
 }
 
 void onTelnetConnect(String ip)
@@ -133,7 +135,7 @@ void onTelnetConnect(String ip)
   Serial.println(" connected");
 
   telnet.println("\nWelcome " + telnet.getIP());
-  telnet.println("Use CTRL+q to disconnect.\n");
+  telnet.println("Use 'CTRL+Q, ENTER' to disconnect.\n");
 }
 
 void onTelnetDisconnect(String ip)
@@ -159,25 +161,29 @@ void onTelnetConnectionAttempt(String ip)
 
 void onTelnetInput(String str)
 {
-  // checks for a certain command
   if (str == "ping")
   {
     telnet.println("> pong");
     Serial.println("- Telnet: pong");
-    // disconnect the client
   }
-  else if (str == "quit")
+  else if (str == "quit" || str == "exit")
   {
-    telnet.println("> disconnecting you...");
+    telnet.println("> disconnecting...");
     telnet.disconnectClient();
   }
+  else if (str == "reboot" || str == "reset")
+  {
+    telnet.println("> rebooting...");
+    ESP.restart();
+  }
 }
 
 DynamicJsonDocument getConfigJson()
 {
-  DynamicJsonDocument doc(1024);
-  doc["brightness"] = defaultBrightness;
-  doc["interval"] = gameInterval;
+  DynamicJsonDocument doc(200);
+  JsonObject config = doc.createNestedObject("config");
+  config["brightness"] = defaultBrightness;
+  config["interval"] = gameInterval;
   return doc;
 }
 
@@ -186,7 +192,8 @@ void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType
   if (type == WS_EVT_CONNECT)
   {
     // client connected
-    logLine("WS: connect");
+    logLine("WS<< connect");
+    logLine("WS>> ping");
     client->ping();
     DynamicJsonDocument doc = getConfigJson();
     size_t strsize = measureJson(doc) + 1;
@@ -198,7 +205,7 @@ void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType
   }
   else if (type == WS_EVT_DISCONNECT)
   {
-    logLine("WS: disconnect");
+    logLine("WS<< disconnect");
   }
   else if (type == WS_EVT_ERROR)
   {
@@ -210,7 +217,7 @@ void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType
   else if (type == WS_EVT_PONG)
   {
     // pong message was received (in response to a ping request maybe)
-    logLine("WS: pong");
+    logLine("WS<< pong");
   }
   else if (type == WS_EVT_DATA)
   {
@@ -218,15 +225,30 @@ void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType
     data[len] = 0;
     logLine("WS<< ", false);
     logLine((char *)data);
-    updateConfig(data);
+    handleJson(data);
   }
 }
 
-void updateConfig(uint8_t *data)
+void handleJson(uint8_t *data)
 {
   StaticJsonDocument<200> doc;
-  deserializeJson(doc, (char *)data);
-  defaultBrightness = (int)doc["brightness"];
+  DeserializationError error = deserializeJson(doc, (char *)data);
+  if (error)
+  {
+    logLine("deserializeJson() failed: ", false);
+    logLine(error.c_str());
+    return;
+  }
+
+  if (doc.containsKey("config"))
+  {
+    updateConfig(doc);
+  }
+}
+
+void updateConfig(StaticJsonDocument<200U> doc)
+{
+  gameInterval = doc["config"]["interval"];
+  defaultBrightness = doc["config"]["brightness"];
   displayBrightness(defaultBrightness);
-  gameInterval = (int)doc["interval"];
 }
diff --git a/src/network.h b/src/network.h
index 2177f8228d2c462ad69ef6d8ceb904fc9bf094a3..f83d9162d5a28c594049c12ff130934000e42d1d 100644
--- a/src/network.h
+++ b/src/network.h
@@ -29,6 +29,7 @@ void onTelnetReconnect(String ip);
 void onTelnetConnectionAttempt(String ip);
 void onTelnetInput(String str);
 void onEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
-void updateConfig (uint8_t* data);
+void handleJson(uint8_t* data);
+void updateConfig(StaticJsonDocument<200U> doc);
 
 #endif