{"id":218,"date":"2015-04-22T07:16:49","date_gmt":"2015-04-22T07:16:49","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=218"},"modified":"2015-04-22T07:16:49","modified_gmt":"2015-04-22T07:16:49","slug":"the-importance-of-ping-times","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/the-importance-of-ping-times\/","title":{"rendered":"The importance of ping times"},"content":{"rendered":"<p>In this brief article we will take a look at the simple concept of &#8220;ping times&#8221; and how we can use it in our multiplayer games to improve the user&#8217;s experience.<\/p>\n<p>The connection speed is the single most important key element in an online game as it affects the whole experience. Being able to detect slow downs and &#8220;hiccups&#8221; could help removing some of the frustration when the client&#8217;s network is not behaving as expected. Also, being able to signal critical network issues could help the final user improve their game performance.<!--more--><\/p>\n<h3>\u00bb The basics of network lag<\/h3>\n<p>When transmitting\u00a0a packet of data over the network\u00a0we&#8217;re literally sending electrical impulses through miles of electrical wires. These impulses must be encoded\/decoded into meaningful data and be checked for validity across a number of devices (routers, gateways, firewalls&#8230;) along the signal path.<\/p>\n<p>Without going into too many\u00a0technical details, the term network lag represents the time for the packet\u00a0to travel from its source to the\u00a0target.\u00a0When we refer to the <strong>ping time<\/strong> or <strong>roundtrip time<\/strong> we usually mean a complete send\/response cycle, in other words: the time from player\u00a0to server + server to player.<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter wp-image-219 size-full\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2015\/04\/ping-time.png\" alt=\"ping-time\" width=\"412\" height=\"171\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2015\/04\/ping-time.png 412w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2015\/04\/ping-time-300x125.png 300w\" sizes=\"(max-width: 412px) 100vw, 412px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>In example above we have a total of 50 milliseconds of roundtrip time, from client to server and back. Ping times can vary greatly due to the type of connection in use (mobile, DSL, optical fiber etc&#8230;), the physical distance between client and server, and the number of nodes (&#8220;hops&#8221;) that are encountered in the path.<\/p>\n<h3>\u00bb Monitoring ping times<\/h3>\n<p>The SmartFoxServer client API allow to easily monitor the client&#8217;s ping time by sampling it every few seconds and calculating an average based on a number of previous measurements.<\/p>\n<p>To activate this function we can invoke the <strong>SmartFox.enableLagMonitor(&#8230;)<\/strong> method after having logged in. There are several ways to call this method (examples are in Java):<\/p>\n<p>Example 1:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">sfs.enableLagMonitor(true);<\/pre>\n<p>This call simply turns on\/off the lag monitor.<\/p>\n<p>Example 2:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">sfs.enableLagMonitor(true, 4);<\/pre>\n<p>Here we specify a second parameter indicating the interval (in seconds) with\u00a0which the lag sampling\u00a0should run.<\/p>\n<p>Example 3:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">sfs.enableLagMonitor(true, 4, 30);<\/pre>\n<p>Here we also pass a third argument indicating the number of samples that should be used to calculate the average ping time.<\/p>\n<p>Finally we can listen to the <strong>SFSEvent.PING_PONG<\/strong> to handle the ping time updates:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nsfs.addEventListener(SFSEvent.PING_PONG, this);\r\n\r\n...\r\n...\r\n\r\n@Override\r\npublic void dispatch(BaseEvent evt) throws SFSException\r\n{\r\n    if (evt.getType().equals(SFSEvent.PING_PONG))\r\n    {\r\n    \tInteger lagValue = (Integer) evt.getArguments().get(&quot;lagValue&quot;);\r\n\r\n    \tSystem.out.println(&quot;Ping time: &quot; + lagValue + &quot;ms.&quot;);\r\n    }\r\n}\r\n<\/pre>\n<h3>\u00bb What do I use the ping time for?<\/h3>\n<p>Being able to monitor the network conditions will help you provide an overall better experience to your players. For example:<\/p>\n<ul>\n<li>Being able to show an on-screen graph of the network performance can help users understand how their connection is working. Further assistance can be provided to players with slow\u00a0connections such as advising them to stop other downloads while playing\u00a0 etc&#8230;<\/li>\n<li>It allows to\u00a0gather statistics about the average network capabilities of players and provide hints on possible further game optimizations for slower connections.<\/li>\n<li>It can also be used as a prerequisite test to check if a player matches the minimum connection speed\/lag to play the game smoothly, especially for fast action games.<\/li>\n<li>It can be very useful in real-time games to compensate for the lag between client and server when sending certain events. For example we\u00a0can detect a collision or similar event, slightly in advance (e.g. 50ms before it occurs) to make up for the current network delay.<\/li>\n<li>It can be useful as a client side log information to troubleshoot specific player&#8217;s complaints and for debugging.<\/li>\n<\/ul>\n<h3>\u00bb\u00a0Full\u00a0example (Java client API)<\/h3>\n<p>The code below shows a basic client performing a connection + login to SmartFoxServer followed by the activation of the <strong>LagMonitor<\/strong> tool.<\/p>\n<p>If you&#8217;re using a platform other than Java on the client side, you will find the same call and related event in your favorite language. You can check the relative documentation to see an example of usage as well.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npackage sfs2x.client.example;\r\n\r\nimport sfs2x.client.SmartFox;\r\nimport sfs2x.client.core.BaseEvent;\r\nimport sfs2x.client.core.IEventListener;\r\nimport sfs2x.client.core.SFSEvent;\r\nimport sfs2x.client.requests.LoginRequest;\r\nimport sfs2x.client.util.ConfigData;\r\n\r\nimport com.smartfoxserver.v2.exceptions.SFSException;\r\n\r\npublic class LagMonitorExample implements IEventListener\r\n{\r\n\tprivate SmartFox sfs;\r\n\r\n\tpublic LagMonitorExample()\r\n    {\r\n\t\tConfigData cfg = new ConfigData();\r\n\t\tcfg.setHost(&quot;localhost&quot;);\r\n\t\tcfg.setZone(&quot;BasicExamples&quot;);\r\n\r\n\t\tinitSmartFox();\r\n\r\n\t\tsfs.connect(cfg);\r\n    }\r\n\r\n\tprivate void initSmartFox()\r\n\t{\r\n\t\tsfs = new SmartFox();\r\n\t\tSystem.out.println(&quot;VERSION: &quot; + sfs.getVersion());\r\n\r\n\t\tsfs.addEventListener(SFSEvent.CONNECTION, this);\r\n\t\tsfs.addEventListener(SFSEvent.CONNECTION_LOST, this);\r\n\t\tsfs.addEventListener(SFSEvent.LOGIN, this);\r\n\t\tsfs.addEventListener(SFSEvent.PING_PONG, this);\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void dispatch(BaseEvent evt) throws SFSException\r\n\t{\r\n\t\tif (evt.getType().equals(SFSEvent.CONNECTION))\r\n\t    {\r\n\t    \tboolean success = (Boolean) evt.getArguments().get(&quot;success&quot;);\r\n\r\n\t    \tif (!success)\r\n\t    \t\tthrow new RuntimeException(&quot;Connection attempt failed!&quot;);\r\n\r\n\t    \tSystem.out.println(&quot;Connected: &quot; + sfs.getConnectionMode());\r\n\r\n\t    \t\/\/ Login as guest in current zone\r\n\t    \tsfs.send(new LoginRequest(&quot;&quot;, &quot;&quot;, sfs.getCurrentZone()));\r\n\t    }\r\n\r\n\t    else if (evt.getType().equals(SFSEvent.CONNECTION_LOST))\r\n\t    {\r\n\t    \tSystem.out.println(&quot;Disconnected: &quot; + evt.getArguments().get(&quot;reason&quot;));\r\n\t    }\r\n\r\n\t    else if (evt.getType().equals(SFSEvent.LOGIN))\r\n\t    {\r\n\t    \tSystem.out.println(&quot;Logged in as: &quot; + sfs.getMySelf().getName());\r\n\r\n\t    \t\/\/ Start measuing ping times\r\n\t    \tsfs.enableLagMonitor(true);\r\n\t    }\r\n\r\n\t    else if (evt.getType().equals(SFSEvent.PING_PONG))\r\n\t    {\r\n\t    \tInteger lagValue = (Integer) evt.getArguments().get(&quot;lagValue&quot;);\r\n\r\n\t    \tSystem.out.println(&quot;Ping time: &quot; + lagValue + &quot;ms.&quot;);\r\n\t    }\r\n\t}\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this brief article we will take a look at the simple concept of &#8220;ping times&#8221; and how we can use it in our multiplayer games to improve the user&#8217;s experience. The connection speed is the single most important key element in an online game as it affects the whole experience. Being able to detect [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[23],"tags":[37,34,7],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/218"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=218"}],"version-history":[{"count":9,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/218\/revisions"}],"predecessor-version":[{"id":228,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/218\/revisions\/228"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}