Quality matters. Your audience does not care about the technology you used to develop your game. The big questions for consumers are: how do I get it, will it run on my device, and is it as good as any other experience I could have on this device. The tough problem for HTML5 is meeting the quality expectations compared to its competitors, and it has taken time for the technology to evolve. Filament Games has heavily invested into HTML5; the following is our vision, strategy, and process for creating high-end HTML5 games.
A Checkered Past
The Current State of HTML5
The promise of HTML5 is applications that can run on any device with a web browser, an idea referred to as “write once, run anywhere.” It is an inherently complicated platform as some browsers only have partial support of the standard and implementation varies. You still need to be knowledgeable about the differences between Chrome, Firefox, Internet Explorer, Safari, Android, as well as the past and proposed future versions of each browser.
HTML5 is just a framework – a core set of essential technology that gives us the capabilities to build rich content. There are two ways to render content DOM versus canvas and you have to very strategically pick out a suite of software layered on top of that core.
What Devices Does Filament Support
There is significant diversity among all devices, and choosing HTML5 as a platform implies your goal is to reach as many devices as possible. The performance of your application is absolutely critical to reach into the phone and tablet market. In the industry we refer to the least common denominator as the “minimum specification” machine or “min spec” for short. Filament Games typically targets the iPad 2, iPad mini, and comparable android devices for min spec HTML5 machines. In addition to the disparity of performance, design accommodations need to be made so that touch interfaces feel as good as using a mouse, and the wide array of potential screen resolutions need to be elegantly supported.
The browser and hardware market shares are public information. Here are browser examples from venturebeat and w3schools and the current tablet market from statista. While general geographic market share is easy information to find, some markets data like school device adoption can be dramatically different and harder to acquire. While HTML5 works on all browsers, the tough problem is identifying the oldest version of a browser to support and navigating the technical implications of going back one more version. The min spec device / browser version is a critical issue to address as it directly affects the capabilities and capacity of the project as well as the cost of quality. This is what Filament Games supported at minimum in our latest HTML5 games:
- iPad 2 / iPad mini running iOS 8
- Nexus 7 / Galaxy Tab 10.1 / HP Slate 10 running Android 4.3
- Internet Explorer 9, Firefox 38, Chrome 43, Safari 6 (the previous 2 versions of each major browser)
How Does Filament Support That Hardware/Software
Though the HTML5 standard can be conceptualized as a list of features all browsers should support, not all of the standard is finalized, and browsers can still decide how to implement those features (performance can vary across browsers). The older the browser, the fewer of those features are supported. We frequently have to reference websites like caniuse or examine compatibility tables on MDN. Any holes in support or deprecated features in browsers lagging behind the standard need to be patched with what are referred to as polyfills.
It is important to note that backfilling support is just as important as looking forward to where the standard is going. Some things as basic as keyboard support (specifically for virtual keyboard on mobile) and requestAnimationFrame (how we request draws of the screen) needs programming to wrap varied support with fallbacks when there is no support. Vast lists of polyfills exist to support as much as possible.
Audio support is tough cross-browser issue; Internet Explorer still uses the HTMLAudioPlugin when most browsers use the WebAudioPlugin. The difference is so extreme that we use two completely different strategies to deliver a rich audio experience. The difference in plugins is compounded by the fact that Internet explorer has a limited amount of sound files that can exist in memory. This limit is particularly crippling because the HTMLAudioPlugin uses audio tags, which means each sound file is linked to one reference in memory. Internet Explorer can only playback one instance of a sound per sound file. In order to support Internet Explorer, we group some sounds into audio sprites, stream sounds that play infrequently where latency on playback is acceptable, and unload sounds when possible.
Filament’s Technology Stack
At this point we examined several HTML5 game engines that supply the rest of the traditional game making logic, including Turbulenz and Phaser. Ultimately we wrote our own support for data structures, geometry, animation, sound, and other things typically available “out of the box” on other platforms like Flash and Unity.
What Sets Filament Apart
This is the nature of the platform, and there are similar stories told by other developers. Everyone has to address these issues, Spil Games, intolabs, and previously mentioned turbulenz all share similar insights on the same tough problems. Filament’s vision of the HTML5 platform is reaching as many devices as possible, and what sets us apart is our expertise in performance. It is surprisingly easy to make a game that will not run on a tablet. Turbulenz has some gorgeous games dedicated to their vision of high end HTML5 games, but at least in the case of Save the Day it does not load or is unplayable on various iPads.
On most devices and browsers we have tools to analyze memory usage and profiling to diagnose issues with framerate, iPads do not have these tools. It is true that there are iOS simulators available that run on Apple laptops which is useful for debugging, but not for insights to maximize the performance of specific hardware. Ultimately we had to resort to testing on analog devices with better tools and tedious black box testing on iPads.
There are several generic concepts that we used to work within this constrained environment. We reused objects as much as possible (static memory, free lists, object pools, etc), and had designs were games could have sections unloaded from memory. Designs also included modular art assets to minimize the overall art memory footprint. Allocating artwork seemed to have extra overhead and in some cases we created art assets ahead of time and distributed the creation over time to avoid memory spikes.
Something specific we discovered was a secondary memory limit for textures on iPad and similar tablets. Roughly, there appears to about 7-8 pages of 1024×1024 of active texture memory; exceeding this amount has performance implications.
Some of Filaments earliest HTML5 projects involved converting children’s books from Flash to HTML5, which gave us a lot of insight into render speed and memory since it was almost completely art with minimal programming. Despite all the artwork of a book fitting in memory, interactive pages suffered significantly until we restructured the project to keep minimal art in memory.
The canvas renderer is very simplistic. By default the canvas object clears the entire screen and redraws everything every frame. There is no clipping or occlusion culling, every- part of every visual object is drawn. There is also significant cost for each individual draw call, so many small and simple objects can still be very expensive to render.
There are many ways to draw fewer objects or draw less often. IBM outlines some of the popular strategies of layering canvas elements redrawing the foreground and background less frequently, and covers the beginnings of writing your own renderer with redraw regions (redrawing only part of the screen, which is common in many 2D systems including Flash).
At Filament we took a slightly different approach. Our strategy to draw less relied on extensive caching. Caching flattens an object into one texture (sometimes referred to as baking) and instructs the renderer to not redraw it. Cached objects can still be moved, rotated, scaled and otherwise transformed, but the tradeoff is that it is a large memory allocation. Display objects still need to be structured in groups and require extra programming to manage when they need to be redrawn; however, art and design can iterate quickly since the source material is still in pieces. Our goal is to render 50 draws or less per frame, and a similar rule of thumb exists at other studios.
In addition to removing vector art from our content pipeline, no texture had a dimension greater than 1024 pixels and any key frame animations were converted to spritesheets. Key frame animations would not play smoothly on min spec devices, at least on their first play through. The necessity for spritesheets, combined with a max texture size of 1024×1024 and a limited number of those textures allowed, created a limited animation capacity.