Lessons Learned from Five Years of Building HTML5 Games



Lessons Learned from Five Years of Building HTML5 Games

0 1


jQueryTO2014


On Github olawson / jQueryTO2014

Lessons Learned from Five Years of Building HTML5 Games

Welcome, my name is... (etc.)

  • A lead game developer at Uken Games
  • One of the first hires at Uken
  • Working with Web Apps and Games for the past 6 years
  • Talking about some of the lessons learned over the past 5 years building games with web technology

Toronto's Largest Independent Game Studio

A little about Uken

  • 5 years old, grown to around 65 people
  • Toronto's largest Independant Game Studio
  • Building on revenue
  • 10 games out, most HTML5 based
  • 7 platforms

Games with Web Technology

Experiences building, lanuching and supporting HTML5 Games

Many top games on mobile platforms are using HTML5

"agonisingly slow-loading assets"(Edge Magazine review of TowerUp, February 1 2012)

  • Talk is about...
  • Our experiences building, lanuching and supporting HTML5 Games
  • Lots of HTML5 game projects, but most are tech demos - I've found it harder to find talks from people sharing successeful, in production games (can live off)
  • I'll go through some specific lessons learned, followed by Q & A
  • Had a lot of success, but also failures (TowerUp) - launched on first gen iPad, then iPhone
  • Though rarer, many top games on mobile are using HTML5

    • Rage of Bahamut

    • Legends of the Cryptids

    • Disney.com - Suite of successful web games designed for mobile

    • Most hybrid apps

So you want to make a game?

What platform will you build for?

How will you package your game?

  • iOS and Android fastest growing games market - 2.9X growth in 2013
  • Pure web or hybrid app? (Hybrid: native app wrapper around a WebView) - Hybrid offers better distribution and access to payments, push notifications, more sensors
  • these are the decisions we went with, and what I'll be focusing on, however the lessons should apply more broadly as well

Canvas vs DOM

Canvas

  • Direct control of rendering
  • Slow & inconsistent
  • WebGL (not ready for mobile)

DOM

  • Rapid development & familiar UI
  • Hardware accellerated CSS3 animations
Next choice, Canvas vs DOM Canvas
  • The canvas element came with the promise of direct rendering control
    • Slow: Large canvas elements can be big performance hogs on mobile when trying to maintain a high framerate
    • canvas graphics libraries are still not that mature when it comes to more advanced techniques like double buffering and dirty rectangles
    • Inconsistent: requestAnimationFrame isn't supported everywhere (iOS 6+, Android 4.4+), and it's not fully reliable on all platforms. Just like intervals and timeouts, the literal time passed between frames isn't very reliable (especially on mobile)
  • WebGL: isn't supported on the major mobile platforms. Other than in custom browsers.
    • http://caniuse.com/webgl (no, basically only reasonable on Chrome or FF)
DOM
  • accessible: everyone knows HTML, especially artists. - Allows different team members to work more collaboratively, blurred lines between designers and developers
  • rapid prototyping and development
  • built in object model
  • CSS3 animations can be hardware accellerated
Verdict
  • Our benchmarks have been mixed.
  • DOM has a higher overhead of creating new elements, and can slow down when there's a high number of animated elements on screen
  • Canvas better for many elements, but can struggle maintaining framerate when drawing a large area every frame
  • Ultimately we've found we can get the best performance for the games we've made using DOM and CSS3

CSS3 Animations

.walking {
  -webkit-backface-visibility: hidden;
  -webkit-animation-name: 'walkingMove';
  -webkit-animation-duration: 4800ms;
  -webkit-animation-timing-function: linear;
  -webkit-animation-iteration-count: infinite;
}

@-webkit-keyframes 'walkingMove' {
  0% { -webkit-transform: translate3d(660px,0px,0px) scale3d(1,1,1)}
  45% { -webkit-transform: translate3d(170px,0px,0px) scale3d(1,1,1)}
  52% { -webkit-transform: translate3d(170px,100px,0px) scale3d(-1,1,1)}
  96% { -webkit-transform: translate3d(660px,100px,0px) scale3d(-1,1,1)}
  100% { -webkit-transform: translate3d(660px,0px,0px) scale3d(1,1,1)}
}
  • high level animation (tweening instructions, not painting)
  • hardware acceleration for CSS3 (most iOS, Android 3.0+)
  • smooth, fast (not blocked)
  • rendering not tied to intervals/timeouts (which are inconsistent)
  • Characters from Mighty Monsters (top down map) - Sprite animations (walk) created using step-start transition timing
  • NOTE Hardware acceleration can be turned off, and performance generally degraded, as battery levels drop
This was put together by our artists using a program called Sencha Animator. It gives them a flash-like interface for creating CSS keyframe animations. Unlike other frameworks it's not reliant on fat javascript frameworks. Exports clean CSS.

Another DOM Example

(function animloop() {
  requestAnimFrame(animloop);
  game.update();
})();

Game.prototype.update = function() {
  var currentTime = (new Date).getTime();
  var delta = (currentTime - this.lastUpdate) / 1000;
  this.lastUpdate = currentTime;
  this.updater(delta);
};

Further DOM example: Super Flappy Doge

Put together by coop student Justin Vanderheide in about 1 week

Might recognise, simple flappy bird clone

Animation done by updating translate3d CSS property on elements

Another DOM Example

Mover.prototype.update = function(delta) {
  this.position.x += this.velocity.x * delta;
  this.position.y += this.velocity.y * delta;
  this.velocity.x += this.acceleration.x * delta;
  this.velocity.y += this.acceleration.y * delta;

  var transform = "translate3d(" +
                  this.position.x * WIDTH_100 + "px," +
                  this.position.y * HEIGHT_100 + "px, 0) " +
                  "rotate(" + Math.atan2(this.velocity.y, ROTATION_LIMITER) + "rad)";
  this.element.style.webkitTransform = transform;
};

High Performance UI

3 Options:

  • Store all UI (HTML, CSS, JavaScript) locally
  • Use client side templating and data binding
  • Cache all content and only refresh what's needed
  • To compete with native games, need a UI that feels responsive
  • We've used all 3
  • Local: If doing an offline only game, bundle UI in app (or use application cache - WordSwap)
  • Data Binding: We've largely moved towards using AngularJS for new games
  • Cache Content: Approach taken on existing games
  • link prefetching generally not yet supported on mobile

Caching Content

function LoadBody(url, targetId) {
  var $currentArea = $(".content_area:visible");
  var $target = $("#"+targetId);

  if (target_id == $current_area.attr("id") || $target.is(":empty")) {
    $.get(url, function( data, status, xhr ) {
      LoadSuccess($target, data);
    });
  } else { LoadSuccess($target, ""); }
}

function LoadSuccess($target, data){
  if (data) { $target.html(data); }
  $(".content_area").hide();
  $target.show();

  //request to reload any potentially changed content
}
  • Very basic approach
  • Can extend with watch attributes that trigger a full refresh
  • And with preloading pages, updating in the background (trade off data usage for performance)

Image Preloading

Problems:

  • Browsers load images with progressive image rendering
Mobile Caching isn't very good
Sometimes browsers refuse to load images
  • remote or large assets can be slow to render
  • get image (or other asset) pop in
  • Mostly images, but page rendering (or other assets: fonts) can also be a factor with multi-part page rendering
  • iOS won’t render offscreen or "display: none;" images
  • <img> tags will not be loaded, even if they’re visible, if the device is low on memory
  • large images loaded in 1024x1024 chunks on iOS - mighty map sprite example
http://www.codinghorror.com/blog/2005/12/progressive-image-rendering.html - Jeff Atwood http://grinninggecko.com/developing-cross-platform-html5-offline-app-1/ (appcache limits)

Image Preloading

Solutions:

  • Write your own cache in the native client
  • Use background-image not <img>
  • Preload in a “visible” container, that has a low z-index
  #preload {
      position: absolute;
      left: 0px;
      top: 0px;
      height: 1px;
      width: 1px;
      z-index: 0;
  }

Warning: background-image bypasses built in memmory limits on UIWebview.
  • gets around browser issues for image preloading
  • A custom native client can cache images, and you can ship important images with your build
  • Don't show the page until window.onload is fired. Or use the iOS webViewDidFinishLoad() method. Every browser is a bit different.
http://www.codinghorror.com/blog/2005/12/progressive-image-rendering.html - Jeff Atwood http://grinninggecko.com/developing-cross-platform-html5-offline-app-1/ (prefetch limits)

Browsers Everywhere

  • Pro: Every modern device has a browser
  • Pro: Almost all mobile browsers use WebKit
  • Con: Not all WebKits are created equaltranslate3d on iOS = hardware accelerationtranslate3d on Android 2.x = broken keyboard

LESSON: Great reach for games, but hitting different platforms is more difficult then it should be

Great thing, everything has a browser, generally WebKit (not always equal)

More recent Android issue: during CSS animations on *some* modern Android browsers (4.2+), elements would tile - fail to repaint previous element locations (like old windows errors)

Other odd bugs: BB10 - Most compliant HMTL5 browser when launched, drop downs didn't work!

Also: not only different performance, but degrade performance differently

Platform Fragmentation

Charts form Apple and Google, so take with a grain of salt

Can't limit yourself to only the latest and greatest (eg, Android)

Represents only 2 main platforms

Android finally has websocket and requestAnimationFrame support

The horror of BlackBerry

Even so, still many different targets with very different browser experiences (next slide)

Platform Fragmentation

iOS

  • 3 form factors
  • 5 resolutions

Android

  • Many form factors
  • Many resolutions
  • Phone specific tweaks

Take a closer look at main two platforms, still have...

Not exclusive to HTML5, but HTML5 isn't a magic bullet either

Game/App Interfaces need to be tighter then documents

Some HTML5 specific things

  • Need *some* responsive design, OR scrolling (scalling often not handled well - TowerUp)
  • CSS Authoring framework is very userfull (Compass)

Thank you

Questions?
Owen Lawsonowen@uken.com @OwenCPL
Special Thanks: Adam Proctor Simon Brooks Justin Vanderheide
Reveal.js (https://github.com/hakimel/reveal.js)