Mozilla

Gaming and the Mozilla Labs Apps Project

In this post I give a quick overview of the Mozilla Labs Apps project and how it and the other technologies at Mozilla relate to gaming. We really are at a point where amazing games can be created on the Web with nothing but open technologies.

A few days ago we launched the developer preview of the Mozilla Labs Apps project, our vision of a distributed Web application platform. This apps project is directly related to our overall mission to better the Web, as recently described by Ragavan Srinivasan:

As part of Mozilla’s mission to make the Web better we believe that apps should be available on any modern Web-connected device, operating system or browser, allowing billions of people worldwide to use and interact with apps.

Today, apps are tied to closed ecosystems. Apps also can’t be used across all devices; data within apps is silo-ed and inaccessible to other apps or Web services; and user choice is limited and undervalued.

In an open ecosystem, developers should have the ability to build apps using open Web technologies and resources. They should then be able to distribute and sell those apps with the reach, flexibility and choice that the Web provides.

It’s important to remember that although we often talk about apps as pieces of software that each serve a particular task, they can also be games. After all, if you pull away the story and graphics, a game is really no different to what you would normally consider as an application — it uses the same platform and programming languages, HTML and JavaScript in this case.

So how does the Mozilla Labs Apps project and the other technologies that we’re working on relate to open Web games? I hope to shed some light on this question in the brief overviews that follow.

Rest assured, Mozilla is very much focused on making the Web a better platform for open Web gaming.

Identifying players with BrowserID

Just like how iOS has services like OpenFeint and the Apple Game Center, games on the Web need open and reliable methods of identifying players. BrowserID is one of our solutions to this problem. It allows players to log into your game using their existing email address, providing a password only once per browser session.

Implementing BrowserID within your game is a simple 3-step process. I advise you to check out the documentation about installation, where you’ll also find some fancy BrowserID buttons to show your players that you support distributed authentication. Right now BrowserID is provided via a JavaScript library. However in the near-future it will be built into Firefox for a seamless experience.

Identifying players in this way is just the first step in providing all sorts of functionality with your game, like friends lists, leader boards, chat, and multiplayer.

Creating immersive gameplay with the Full Screen API

Something that prevents current games on the Web from feeling immersive is that they look like they’re just tiny boxes embedded into another website. Why do they feel like that? Well, because they are just tiny boxes embedded into other websites. The odd 5-minute puzzle game during your lunch hour might feel OK in a tiny box surrounded by browser UI and other distractions, but a first-person shooter or driving game certainly wouldn’t.

Fortunately, the Full Screen API has arrived to solve this problem. It allows you to make any DOM element fill the player’s entire screen, something normally only considered for videos. Using this in a game can make the difference between 5 minutes of relative fun and hours of immersive delight.

Like most of the JavaScript APIs, it’s pretty easy to implement full-screen functionality in your game. All you need to do is call the requestFullScreen method on the desired DOM element:

var elem = document.getElementById("myGame"); if (elem.requestFullScreen) { elem.requestFullScreen(); } else if (elem.mozRequestFullScreen) { elem.mozRequestFullScreen(); } else if (elem.webkitRequestFullScreen) { elem.webkitRequestFullScreen(); } 

Taming mouse input with the Mouse Lock API

An issue related to input in games is that of misbehaving cursors, where the mouse is used to rotate a player around a fixed point, like moving the viewpoint in a 3D first-person shooter, or rotating the player in a top-down 2D game.

In both of these situations, the mouse cursor is visible at all times, which is generally annoying and ruins the experience. However, the most debilitating problem is that when the mouse cursor leaves the browser window all movement stops. This same behaviour occurs in full-screen mode when the mouse cursor hits the edge of the screen. It’s a horribly simple problem for players that completely ruins the experience.

The good news is that the Mouse Lock API has been created to solve this problem, and it just landed in experimental builds of Firefox Nightly. Its sole purpose is to tame the mouse by hiding the cursor and locking it in place so it doesn’t hit the edges of the screen. This means that instead of relying on x and y coordinate values for mouse position in related to the top-left corner of the browser, you instead rely on x and y distance values from the position that the mouse was locked to.

Using the Mouse Lock API is really just a case of calling the navigator.pointer.lock method. However this must be done in full screen mode to work properly (and remember to use the experimental build of Firefox linked previously).

The following example expands a <div> element to full screen and locks the mouse in place at the same time:

<script> function fullAndLock() { var div = document.getElementById("div"); document.addEventListener("mozfullscreenchange", function() { var pointer = navigator.pointer; if (document.mozFullScreen && document.mozFullScreenElement === div && !pointer.islocked()) { function onMouseLockSuccess() { console.log("Mouse successfully locked"); } function onMouseLockError() { console.log("Error locking mouse"); } pointer.lock(div, onMouseLockSuccess, onMouseLockError); } }, false); div.mozRequestFullScreen(); } </script> <button onclick="fullAndLock();">Mouse Lock</button> <div id="div">Element to receive mouse lock</div> 

Here is a quick video of the Mouse Lock API in action, with comparison to non-mouse lock game-play to see the improvement:

Providing a console-like experience with the Gamepad API

Another input-related improvement that is coming to the Web is that of the Gamepad API. No longer are the keyboard and mouse the only options available for your players to engage with your game. The Gamepad API now allows for all sorts of gamepads to be accessed via JavaScript. This even includes some of the console controllers like those on the xBox 360 and Playstation 3 (with third-party drivers)!

Like the Mouse Lock API, the Gamepad API has just landed in experimental builds of Firefox Nightly and it’s nice and simple to use. Coupled with the Full Screen API, gamepad support can really change the experience of your game from that of a game within a website to that of a desktop game or console.

To find out when a gamepad has been connected, you need only listen to the MozGamepadConnected event on the window object (remember to use the experimental build linked previously):

<div id="gamepads"></div> <script> function gamepadConnected(e) { var gamepads = document.getElementById("gamepads"), gamepadId = e.gamepad.id; gamepads.innerHTML += " Gamepad Connected (id=" + gamepadId + ")"; } window.addEventListener("MozGamepadConnected", gamepadConnected, false); </script> 

Receiving updates about all the buttons and joysticks on a gamepad is also a case of listening for events, or you can manually poll the status of buttons and joysticks whenever you want. Check out the Gamepad API documentation and the input.js library for more information.

The video below shows the Gamepad API in action, controlling a player in the game Rawkets:

Adding real-time multiplayer game-play with WebSockets

If you’re thinking of creating a multiplayer game then before now you would either have put up with the latency involved in constant AJAX requests, or you would have moved to Flash. Neither option is ideal. What’s cool is that since last year this is no longer the case, WebSockets have now arrived to allow for real-time bi-directional communication between the browser and a server.

But why is bi-directional real-time communication important for games? Well, this means that you can now literally stream data to and from a player’s browser in real time. One obvious benefit to this is that it saves bandwidth by no longer requiring constant AJAX requests to check for new data. Instead the WebSocket connection is left open and data is instantly pushed to the player or server as soon as it is needed. This is perfect for fast-paced games that require updates every few milliseconds. On top of this, the bi-directional nature of WebSockets means that data can be instantly sent both from the server to the player and from the player to the server at the same time.

Using WebSockets is a case of connecting to the socket server by initialising the WebSocket object:

var mySocket = new WebSocket("http://www.example.com/socketserver",); 

From there you can send data using the send method of the WebSocket object:

mySocket.send("Here's some text that the server is urgently awaiting!"); 

And you can receive data by listening for the onmessage event on the WebSocket object:

mySocket.onmessage = function(e) { console.log(e.data); } 

A full code example for game communication would be too much for this post but you should definitely check out the tutorial that that I made a couple months ago. In it I detail exactly how to create a real-time multiplayer game using Node.js and WebSockets.

Using games offline with local storage and the application cache

Creating games on the Web is all well and good, but what about if you want to play that game offline? Or, what if the player’s Internet connection drops out half way through an epic gaming session? Most open Web games today would at worst simply stop working as soon as an Internet connection fails, and at best they would stop sending data to your server and saving player data. When your player refreshes the page that the game is on, they’ll just see a blank page and all their hard work achieved while offline will have been lost. That probably won’t make your players very happy, and unhappy players are not ideal.

There are a few solutions available today that can help solve these issues. The first is the application cache, which allows you to use a cache manifest to declare particular assets (like HTML, CSS, images, and JavaScript) that you would like the browser to cache for offline use. Not only that, the browser uses the cached versions of the files when when online to speed up the loading process.

You can include a cache manifest within your game by using the manifest attribute of the <html> element:

<html manifest="example.appcache"> <h1>Application Cache Example</h1> </html> 

Writing a cache manifest is straightforward and requires you to follow a simple format to declare the files that you want cached. For example, the manifest below looks for /example/bar online and falls back to the locally-cached example.html file if your player is offline or experiencing network issues:

CACHE MANIFEST FALLBACK: example/bar/ example.html 

There is much more to cache manifest than this, so I advise you to read the documentation to discover it in detail.

Another technique you can use is to store a player’s game data locally and periodically sync it with the game server. Normally you wouldn’t be able to store enough data in the browser to achieve this (like with cookies) but with Local Storage and IndexedDB, you can now store many megabytes of data in a structured way.

You can also add functionality to your game so it is alerted when a player’s Internet connection goes offline. The navigator.onLine property allows you to use JavaScript to see if your player is currently online or not. You can also use the offline and online events to trigger automatic behaviour in your game when a change in connection occurs, like stopping all WebSockets communication and caching player data locally until the connection is back.

Creating native OS applications with WebRT

One of the more profound aspects of the Mozilla Labs Apps project is the integration of a Web run-time (WebRT). This allows players to install your game “natively” on their chosen operating system (Windows, Mac, and Android right now), with a launch icon just like standard OS applications.

Installing Web apps natively

WebRT also runs your game using an app-centric user agent (in contrast to browser-centric user agents like Firefox) and runs your game using a separate user profile and OS process to your player’s normal Firefox that they use for browsing.

The ability of WebRT to break away into another process and remove all the browser UI makes the experience for gaming that much sweeter. There’s something about having an icon in the dock on a Mac that launches your game in it’s own “native” window with no mention or feel that this is a browser.

Rawkets Web app

As a developer this is slightly magical. It allows you to break free from a game being a glorified website, instead turning it into an application, an experience in its own right. Mark my words, this will be a turning point in the transition from 5-minute puzzle games on the Web to professional-grade games that have a console-like experience.

The great news is that enabling WebRT on your game is just a case of creating an app manifest and calling the navigator.mozApps.install method through JavaScript.

This is an example app manifest from the Rawkets game:

{ "name":"Rawkets", "developer": { "name":"Rob Hawkes", "url":"http://rawkes.com" }, "description":"Space shooter game.", "icons": { "16": "/style/img/icon-16.png", "48": "/style/img/icon-48.png", "128": "/style/img/icon-128.png" }, "launch_path": "/index.html", "installs_allowed_from": ["*"] } 

As you can see it’s a simple JSON structure. You would then need to pass that manifest file in the call to the navigator.mozApps.install method:

function installCallback(result) { // great - display a message, or redirect to a launch page } function errorCallback(result) { // whoops - result.code and result.message have details } navigator.mozApps.install( "http://rawkets.dev:8000/manifest.webapp", installCallback, errorCallback ) 

This is the most basic implementation possible and would result in a panel popping up in the player’s browser asking if they’d like to install your game and whether they’d like that installation to be a native app or not (like the screenshot above).

Making money from your passion with the Mozilla Labs Apps project

Finally, the last thing about the apps project that I want to cover is that of making money from your game. Let’s be honest, if you can’t make a living from something then you’re going to have a hard time keeping it up for a long period of time.

For the Mozilla app marketplace we are using PayPal as the payment provider. All you need do is set a price on the store and the rest will happen automatically as people start paying for your game — you’ll start receiving money in your PayPal account.

In the future you’ll be able to provide your game on your own website or another store and charge for it there also. This means you’ll be able to use your own payment provider.

Scratching the surface

These technologies are really just scratching the surface when it comes to creating games on the Web using open technologies. At Mozilla we’re working hard to bring you these APIs and services to help make the Web a better place for games. The year 2012 will be a game-changer, for sure (pun intended).

Keep an eye on this blog as we’ll be sure to post more updates and guides as our gaming technologies and the apps project mature.

In the meantime, here are a few of places to go for extra information on the Mozilla Labs Apps project and gaming at Mozilla:

10 comments

Comments are now closed.

  1. Francois MAROT wrote on December 19th, 2011 at 05:54:

    Regarding the gamepad API, I took a fast look at it and it is great. But I wonder: wouldn’t it be illogical to be able to poll a gamepad state thanks to this API but not be able to poll the keyboard state ?
    To my knowledge, there still isn’t ant standard API to poll keyboard state. It would be very strange if a game had to code one way for handling gamepads and another for handling the keyboard…

    For the record I’ve coded a little utility to do keyboard state polling in js but on Firefox, when used in a gameloop and requestNextAnimation frame events do not seem to be called in realtime: https://github.com/fmarot/Misc/blob/master/javascript_gamequery_simple/js/libs/kberty.js

    Any idea if such a keyboard API could be integrated in Gamepad API ?

    1. Rob Hawkes wrote on December 19th, 2011 at 08:03:

      Hi Fancois, thanks for your comment. I know that keyboard polling is something that I have seen discussed, however as of yet I’m unaware of the outcome. I believe the sentiment exists that the ability to poll the keyboard in this way would be benificial.

      Until a more definite decision is made I would jump in the #paladin channel on irc.mozilla.org and have a chat to the developers working on the Gamepad and other gaming-related APIs.

  2. Randell Jesup wrote on December 19th, 2011 at 13:31:

    Coming a little further in the future to Firefox is WebRTC, which will expand on what WebSockets offers by allowing peer-to-peer links (lower latency, lower server overhead for game devs) both for data channels and allow peer-to-peer audio and video between browsers/players. Also, the data channels should provide both reliable as well as unreliable (UDP-like) and partly-reliable (limited retries) channel types, plus it may allow for out-of-order delivery.

    (I’m a lead engineer with WebRTC at Mozilla and member of the IETF and W3C groups defining and implementing this.)

    http://webrtc.org/

  3. sung wrote on December 20th, 2011 at 20:20:

    I’m a little concerned about using paypal as primary payment provider. My foreign friends always complain about not being able to pay using paypal.

    1. Justin Scott wrote on December 22nd, 2011 at 04:19:

      Hi Sung,

      One of the main reasons we chose PayPal as our primary payment option is its extensive international support. If your friends can’t use it, I’m curious to know what countries they’re in and any details, as we want to make sure apps are available in as many places as possible. Thanks.

      1. sung wrote on December 22nd, 2011 at 12:08:

        Hi,

        The friend lives in EU, and I originally heard the complaint while we were talking about kickstarter and how they don’t allow international donors.

        Now that I think about it the issue might be with the KS platform itself, since I’ve been dealing with international sellers using paypal on ebay and such…

  4. pete wrote on December 22nd, 2011 at 09:39:

    please no, last thing firefox needs is to be more bloated and even slower

    1. Rob Hawkes wrote on December 22nd, 2011 at 10:00:

      Hi Pete. What makes you think that this functionality would bloat Firefox and make it slow? If anything, Firefox is getting faster with each release.

  5. Gabe wrote on December 23rd, 2011 at 08:34:

    All the projects look great and open a full range of possibilities. It’s exiting. I would like to know how coordinated is your work with Google and the other mayor browser providers. I read on netmagazine.com that you are closely working with Google, does that mean that Google will offer similar applications as Firefox for Chrome? From what I know, MS is going slow on the implementation of HTML5 because they what the standard to be completed (just so the know how to break it), but what do you know about their engagement with Web Gaming? Good luck and marry x-mas!

  6. Mike wrote on May 30th, 2012 at 23:03:

    What if we don’t want to have a major server side component that depends on the user being online and authenticated? How can developers protect games or apps in general if we are using WebRT with offline features?

    I’m not sure how serious app development can pick up without addressing protection. I’m all for openness and using Web tech for apps but lets be real. This may work in the US but if we are trying to make money on web apps in China for example, we are practically giving away all our code for free and people will happily copy it and we will end up with a small paying user base.

Comments are closed for this article.