Introduction

So, you've spent months building up your game backend on GameSparks and launch is imminent. How will your game's server hold up when hundreds or thousands of players download your game, connect to GameSparks, and bombard it with requests? How long will a request take to send, be processed, and respond to the client? Don't leave this to chance! Being able to monitor and react to your game's performance is critical to running a successful game as a service. 


Fortunately, GameSparks provides a number of developer tools that you can utilize to analyze and identify performance issues, so that you are better placed to optimize the player experience. Let's have a look at a few of these key tools and demonstrate how you can empower your developers.


Summary of Tools

  • Analytics Overview - view certain performance analytics, such as average response time, average Javascript execution time, and average requests per player.
  • API Stream - central hub for websocket traffic - all requests, responses, and messages between game clients (or the Test Harness) and GameSparks can be viewed in detail here. 
  • Script.log - Cloud Code script errors are logged here with full stacktrace and you can use it for various other logging types (debug, info, and so on).
  • Profiler - allows you to collect and inspect per-function performance metrics for your Cloud Code scripts.


Analytics Overview

This is a great place to start for a quick snapshot of your game's performance. Please read through our Analytics Overview guide to understand the key charts.


The key performance-related metrics to look out for here are:

  • Average Response Time (ms) - round trip time from request to response.
  • Average Javascript Execution Time (ms) - how long it takes your Cloud Code scripts to execute.
  • Average Requests per Player - you need to keep this within our Fair Usage Policy (for performance reasons). It averages at 166 requests per day, per user.


From this overview, the next step is a deep dive into the API Stream.


API Stream

The API stream is simply that, a stream of API requests and messages made between game clients and GameSparks. This lets you monitor exactly what data is sent via a request, response, or message. You can also view performance metrics such as Count of Requests or Duration, which will give you an indication of the average time it takes for a request to be processed, that is, the duration from when GameSparks receives the request, through processing the Cloud Code for the Event, to when the response is sent. This will give you a very good indication of which of your game's Cloud Code scripts could benefit from some optimization. Before you continue, please follow our API Stream guide to understand its various components.


Let's have a look at all API activity in my game:



As you can see in my results, two of my requests are well over what you should deem 'acceptable'. We should look at where we can make improvements to this script. Generally, we recommend script duration to be kept well under 1000ms (obviously, the lower, the better!) to ensure a smooth play experience. To build a better picture, you should change the Calculation to % of Unique Players and then Count of Requests. This will tell you what % of the player base is affected and how often by a problematic request. This can help you in prioritizing which scripts to tackle first - there may be some real low-hanging fruits in there.


Viewing a raw request in the Data Table is also useful for viewing any errors in your API calls - simply query by Response Error = is not empty and inspect the results. The response errors are usually fairly descriptive and include a full stacktrace to pinpoint which piece of code is causing the error.



Script.log

Script.log is a runtime collection which stores logging information. A summary of the counts of each log level can be viewed on the Game Overview page. FATAL and ERROR logs are created automatically by the system and WARN, INFO and DEBUG are user-level logs that you can add to your scripts by using Spark.getLog().level("message"):



FATAL and ERRORS, oh my!

  • FATAL - usually mean that a script has timed out. There's a 30 second timeout rule applied to Cloud Code scripts. So if you experience this, it's likely that the computation performed by the script is taking too long and needs to be optimized.
  • ERROR  - 'errors' usually means that your script is trying to reference a function or piece of data that doesn't exist.


To view the individual logs in the script.log collection, navigate to Data Explorer > Collections > Runtime. You can query by level using the following syntax - {"level":"value"}. By expanding the results, you can see the stacktrace information which will help you pinpoint the problematic Cloud Code:



Profiler

The Profiler is a very useful tool for capturing Cloud Code performance metrics. By inspecting and analyzing these performance metrics, you can quickly identify and address performance issues that arise for any of the Cloud Code you've built into your game. Please read our Profiler guide to understand the key components.


Any Cloud Code script can be profiled and to do so simply turn on the Profile flag on the Test Harness prior to sending an Event:




Once you send a request, click on the View profile button to go into the Profiler where you can inspect the metrics.


In the Profile window, you can toggle the Metric to either Statements, which give the number of statements, or Time (MS), which gives the execution time in milliseconds. Calls to Mongo or Redis are appropriately flagged to make it easier to identify performance-costly queries. Going back to the Duration metric in the API Stream, we advised you to keep script executions well below 1000ms, so have a look at which queries or statements are costing the most resources and make optimizations to bring the total cumulative MS below this recommended level. 



With these tools available to you, you should be able to build a very clear picture of how you can make performance-boosting optimizations to your game to ensure a optimal player experience.