In this second bonus episode, let’s do some tooling to help the devs debug 🙂
This article is also available on Medium.
In the first bonus episode, we added various improvements to our game like camera shakes, fog in the distance or bonus popup labels. These are little things that make the overall player experience better.
But it’s also important to think of the people making your game and that’s why tooling is important!
This tutorial is available either in video format or in text format — see below 🙂
A quick recap on tooling
In a nutshell, tooling is a specific subdomain of development that specially focuses on making interfaces and consoles to monitor internal and debug info on your program, and give some feedback to the devs on the project.
So it’s about creating tools that aren’t always pretty, but that’s not the point. The point is to show data in an intuitively readable manner so that the people who work on the game can analyse it easily and potentially find or fix bugs.
The tools can take various forms, from just an in-game console to a full-fledged dynamic inspector of a 3D scene hierarchy. They have to be made specifically for your team and adapted to your needs, they are not generic. Finally, depending on the tool, it may or may not be exported in the final shipped game build.
In our case, we are going to create a basic stats panel that shows the current frame render time, allocated memory and FPS of the app and that can be toggled by pressing the
<Enter> key. We don’t really discriminate between dev and prod builds, so we can say that it will be shipped in the final version – even if not many players will take a look at it! 😉
This lib is a lightweight class that allows you to quickly spawn info graphs in your DOM that give you a real-time analysis of predefined or custom user-computed values. In our case, we’ll mostly stick with the predefined ones and focus on the FPS, MS and MB stats.
As explained in the docs:
- FPS is the number of frames that were rendered in the last second.
- MS is the number of milliseconds needed to render a frame.
- MB is the amount of memory allocated to our app.
As usual, we can get a minified version of the lib by going on the Github, in the
build/ folder; and copy this .min.js file to our
Then, we’ll simply import it in the
index.html and we’re ready to go!
Instantiating our stats panels
To keep our codebase clean, let’s create a new file called
stats-manager.js and import it in the
index.html as well.
Then, inside this file, let’s create a small class called
This class will first create our stats panels and add them to the DOM, and then store a reference to each of these panels so that it can update them later on in our animate loop.
But before we actually dive into the JS, let’s first create a container for this info in our HTML file. We’ll just create a new div with id “stats” in our
Then, in our CSS file, we can add some style to this div so that we’re sure it is printed on top of the rest of our elements, in the top-right corner.
And finally, we can now use the stats.js lib to actually populate this div with debug panels!
Let’s go back to our
stats-manager.js file and, in the
StatsManager class, add a constructor.
In here, we’ll first get a reference to our stats div. Once again, I use the
animate() function afterwards.
And so these objects are created by using the stats.js lib, just by creating a new
Stats() object and calling its
showPanel() method with the right debug panel id. For example, id 0 is the FPS panel, then id 1 is the MS variable and finally id 2 gives me the allocated memory stat.
Since I want those three panels, I can wrap my panel creation inside a basic for-loop that goes from 0 to 2 (included) and calls the JS constructor and its
showPanel() method. Once I’ve created my panel, I need to show it in the DOM by appending its DOM element to my stats div.
And, finally, I’ll push this new stat panel to my list of stats.
With this little loop, I therefore have my 3 panels properly set up.
If I go to my
main.js and create a new
StatsManager in my
onload() callback, you see that when I refresh my page I now have a bunch of debug panels on the right!
Something important to note, though, is that the memory debug relies on the
memory property of the Performance object which is an experimental feature that is only available for chromium-based browsers, but for example not on Firefox or Safari.
So if you run the code on a Firefox browser, you won’t see the third panel…
Actually updating the data
With that said, you also see that, at the moment, those panels aren’t really displaying any data. They have been added to the DOM as empty frames and stay still all throughout the game.
To have them update and show the up-to-date data, we need to call the
update() method of the
Stats objects we stored.
Let’s do this in a new function, inside our
update(). This method will just iterate through our
this.stats array and call the
update() function on each item:
Then, in our
main.js file, in the animate loop, just below the
gameInstance.update() line, we can add to update the stats manager, too:
And if we refresh this, we see that the panels are now updating and showing some actual data 🙂
As you run the game, you should see some slight fluctuations – but our game is clearly not too heavy, so these should stay at pretty good levels on most computers!
Adding a toggle shortcut
Finally, let’s add a shortcut to toggle our debug panels on and off – this way, we’ll initially hide it and only the ones who are interested will display it.
StatsManager class, we’ll add a new boolean flag,
this.active, that will prevent us from updating the data if the panel is hidden. It’s like the
running flag in our
Game instance: if this value is false, then we’ll skip the update process altogether.
This will avoid doing useless computation and improve the performance of our app a little bit.
Then, let’s also add a
_toggle() function that switches the value of this flag and shows or hides the
this.statsDiv panel accordingly:
And to wrap this up, let’s do the same as in our
Game class and have a callback on the keydown event that calls this toggle function if we press the
I’ll also call the
_toggle() function once at the end of the constructor so that the panel is hidden at first.
And now, whenever I press the Enter key, my panel is toggled on or off and the data is updated only when I see the stats panels.
So there you have it! 🙂
In this episode, we saw how to add simple debug panels that can be toggled on or off using the stats.js library. It is not fully cross-browser compatible because it relies on the memory property of the Performance API that is not available everywhere, but it is already a basic example of tooling, and it can help you quickly catch if something is wrong with your game.