Fancy learning the basics and getting your first game up and running on your Azure Web Services, well this guide will show you have to build a game with Web technologies.
The following blog will take you through a step by step guide of building a game from scratch using Web technologies and just two external javascript libraries.
Building a web based game is the perfect Hour of Code and the aim if for you to have the game live within one hour. This blog covers the basic game design and screen layout, controls and sprites and includes an artificial intelligence (AI) as a simple opponent.
Step 1. Tools and Technologies
Download Visual Studio Community or Visual Studio code from www.dreamspark.com
I will be using Visual Studio Community and the Microsoft Azure SDK.If you have a Mac or Linux user, Visual Studio Code is available cross-platform and perfect for building web sites.
Create your DreamSpark Azure Subscription which give you FREE web apps see http://blogs.msdn.com/b/uk_faculty_connection/archive/2015/09/14/accessing-microsoft-dreamspark-azure-account-if-you-have-onthehub-dreamspark-premium.aspx
This app will require no server code, so I start by creating a new, empty Web page project in Visual Studio.
Step 2. Creating a ASP.Net Web Site
I’ll use the empty C# template for a Web site by selecting the Visual C# option after selecting File | New | ASP.NET Empty Web Site.
Select an Empty ASP.Net Web Site
If you already have your Azure account setup up you will be promoted to configure your Microsoft Azure Web App Settings for publishing
If you have got this configured see http://docs.asp.net/en/latest/tutorials/publish-to-azure-webapp-using-vs.html or see my previous blog http://blogs.msdn.com/b/uk_faculty_connection/archive/2015/07/19/using-visual-studio-2015-and-deploying-your-first-web-app-to-your-free-azure-subscription.aspx
The index HTML file requires just three resources: jQuery, a main style sheet and a main JavaScript file. I add an empty CSS file to the project called style.css and an empty JavaScript file called ping.js to avoid errors when loading the page as we will be editing both style and ping during this project.
To create these new files right click on the new create web app in the solution explorer and select Add
1:<!DOCTYPE html>
2:<html>
3:<head>
4:<script
5: src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
6:<script src="ping.js"></script>
7:<link rel="stylesheet" href="style.css"></script>
8:</head>
9:<body>
10:</body>
11:</html>
Step 3. So what is the game
This game is based on Pong, except that either player grabs the ball when it comes to them and can then fire the ball back either directly or at an angle up or down. It’s often best to draw how you would like the game to look before you build it. For this game, the overall layout I want to see is shown below.
Once I’ve developed the game design layout, it’s just a matter of adding each element to HTML to build the game. One thing to note, though, is I’ll group the scoreboard and controls to ensure they sit together. So one by one, you can see I’ve added the elements, as shown below:
1:</body>
2:<div id="arena">
3:<div id="score">
4:<h1>
5:<span id="playerScore">0</span>
6:<span id="opponentScore">0</span>
7:</h1>
8:</div>
9:<div id="player"></div>
10:<div id="opponent"></div>
11:<div id="ball"></div>
12:<div id="controls-left">
13:<div id="up"></div>
14:<div id="down"></div>
15:</div>
16:<div id="controls-right">
17:<div id="left"></div>
18:<div id="right"></div>
19:</div>
20:</div>
21:</body>
Step 4. Styling the Game using CSS
If you were to load this page, you wouldn’t see anything because there’s no style applied. I’ve already set up a link to a main.css file in my HTML,
We now need to create main.css.
The first thing I’ll do is position everything on the screen. The body of the page needs to take up the whole screen, so I’ll set that up first:
1: body {
2: margin: 0px;
3: height: 100%;
4: }
Second, I need to have the arena fill the whole screen with the arena background image (see image below) applied:
1: #arena {
2: background-image: url(arena.png);
3: background-size: 100% 100%;
4: margin: 0px;
5: width: 100%;
6: height: 100%;
7: overflow: hidden;
8: }
The background
I want the scoreboard to appear top and centre, over the other elements.
The command position: absolute lets me place it wherever I want and left: 50% places it halfway across the top of the window, but starting at the leftmost side of the scoreboard element. To ensure it’s perfectly centered, I use the transform property and the z-index property ensures it’s always at the top:
I also want the text font to be used, Most modern browsers let you include actual fonts.
I found the appropriate Press Start 2P font from codeman38 www.zone38.net
To add the font to the scoreboard, you have to create a new font face in the style.css
1: @font-face {
2: font-family: 'PressStart2P';
3: src: url('PressStart2P.woff');
4: }
1: #score {
2: position: absolute;
3: z-index: 1000;
4: left: 50%;
5: top: 5%;
6: transform: translate(-50%, 0%);
7: }
The scores are in an h1 tag of index.html, so I can set the font for all h1 tags. Just in case the font is missing,
To do this simply add the following to style.css
1: h1 {
2: font-family: 'PressStart2P', 'Georgia', serif;
3: }
For the player, ball and control icons I will be use a simply sprite sheet
I have a single sprite sheet that contains all the images I need for the game in one file sprites.png
As you can see I have two different colour players ball and control arrows
We now need to assign the sprite class element to style.css
Then, for each element, I’ll use background-position to define what part of the sprite sheet I want to show:
1: .sprite {
2: background-image: url("sprites.png");
3: width: 128px;
4: height: 128px;
5: }
Next, I’ll add the sprite class to all elements that will use the sprite sheet.
1:<div id="player"class="sprite"></div>
2:<div id="opponent"class="sprite"></div>
3:<div id="ball"class="sprite"></div>
4:<div id="controls-left">
5:<div id="up"class="sprite"></div>
6:<div id="down"class="sprite"></div>
7:</div>
8:<div id="controls-right">
9:<div id="left"class="sprite"></div>
10:<div id="right"class="sprite"></div>
11:</div>
To do this I simply need to add all the element into the <div> section of <body> in index.html
Add the following back to your index.html
Now I need to indicate the positions of each sprite on the sheet for each element. Again, I’ll do this using background-position in Style.css
1: #player {
2: position: absolute;
3: background-position: 0px 128px;
4: }
5: #opponent {
6: position: absolute;
7: background-position: 0px 0px;
8: }
9: #ball {
10: position: absolute;
11: background-position: 128px 128px;
12: }
13: #right {
14: background-position: 64px 192px;
15: }
16: #left {
17: background-position: 64px 0px;
18: }
19: #down {
20: background-position: 128px 192px;
21: }
22: #up {
23: background-position: 128px 0px;
24: }
The position: absolute property on the player, opponent and ball will let me move them around using JavaScript. If you look at the page now, you’ll see the controls and the ball have unnecessary pieces attached to them. This is because the sprite sizes are smaller than the default 128 pixels, so I’ll adjust these to the right size. There’s only one ball, so I’ll set its size directly in spirtes.css
1: #ball {
2: position: absolute;
3: width: 64px;
4: height: 64px;
5: background-position: 128px 128px;
6: }
There are four control elements (buttons the user can press to move the player about),. I’ll also add a margin so they have a little space around them:
1: .control {
2: margin: 16px;
3: width: 64px;
4: height: 64px;
5: }
After adding this class, the game has much better looking controls:
Edit index.html and add
1:<div id="controls-left">
2:<div id="up"class="sprite control"></div>
3:<div id="down"class="sprite control"></div>
4:</div>
5:<div id="controls-right">
6:<div id="left"class="sprite control"></div>
7:<div id="right"class="sprite control"></div>
8:</div>
The last thing I need to do is position the controls so they’re by the user’s thumbs when the page is running on a mobile device. I’ll stick them to the bottom corners:
so edit style.css
1: #controls-left {
2: position: absolute;
3: left: 0; bottom: 0;
4: }
5: #controls-right {
6: position: absolute;
7: right: 0; bottom: 0;
8: }
One nice thing about this design is everything is set with relative positions.
This means the screen can be a number of different sizes while still making the game look good so this game will support mobile, desktop and tablet devices.
Step 5. Making the Game Work
We now need to create ping.js
I’m going to make objects for the ball and each of the players, but I’ll use the factory pattern for the objects.
This is a simple concept. The Ball function creates a new ball when you call it. The following pattern reduces some of the confusion around the this variable by clarifying the available object properties. And because we only have an hour to make this game, I need to minimize any confusing concepts.
The structure of this pattern, as I make the simple Ball class:
1: var Ball = function( {
2:// List of variables only the object can see (private variables).
3: var velocity = [0,0];
4: var position = [0,0];
5: var element = $('#ball');
6: var paused = false;
7:// Method that moves the ball based on its velocity. This method is only
8: used
9:// internally and will not be made accessible outside of the object.
10: function move(t) {
11: }
12:// Update the state of the ball, which for now just checks
13:// if the play is paused and moves the ball if it is not.
14:// This function will be provided as a method on the object.
15: function update(t) {
16:// First the motion of the ball is handled
17:if(!paused) {
18: move(t);
19: }
20: }
21:// Pause the ball motion.
22: function pause() {
23: paused = true;
24: }
25:// Start the ball motion.
26: function start() {
27: paused = false;
28: }
29:// Now explicitly set what consumers of the Ball object can use.
30:// Right now this will just be the ability to update the state of the
31: ball,
32:// and start and stop the motion of the ball.
33:return {
34: update: update,
35: pause: pause,
36: start: start
37: }
To create a new ball, I simply call this function I’ve defined:
var ball = Ball();
Now I want to make the ball move and bounce around the screen.
First, I need to call the update function at some interval to create an animation of the ball.
Modern browsers provide a function meant for this purpose called requestAnimationFrame.
This takes a function as an argument, and will call that passed-in function the next time it runs its animation cycle. This lets the ball move around in smooth steps when the browser is ready for an update. When it calls the passed-in function, it will give it the time in seconds since the page was loaded. This is critical for ensuring animations are consistent over time. In the game, the use of requestAnimationFrame appears as follows:
In Ping.js add the following at the top of the file
1: var lastUpdate = 0;
2: var ball = Ball();
3: function update(time) {
4: var t = time - lastUpdate;
5: lastUpdate = time;
6: ball.update(t);
7: requestAnimationFrame(update);
8: }
9: requestAnimationFrame(update);
10: Note that requestAnimationFrame is called again in the function, as the ball
11: has finished updating. This ensures continuous animation.
12: While this code will work, there may be an issue where the script starts
13: running before the page is fully loaded. To avoid this, I’ll kick off the code
14: when the page is loaded, using jQuery:
15: var ball;
16: var lastUpdate;
17: $(document).ready(function() {
18: lastUpdate = 0;
19: ball = Ball();
20: requestAnimationFrame(update);
21: });
Because I know the speed of the ball (velocity) and the time since its last update, I can do some simple physics to move the ball forward:
1: var position = [300, 300];
2: var velocity = [-1, -1];
3: var move = function(t) {
4: position[0] += velocity[0] \* t;
5: position[1] += velocity[1] \* t;
6: element.css('left', position[0] + 'px');
7: element.css('top', position[1] + 'px');
8: }
Try running the code and you’ll see the ball move at an angle and off the screen. This is fun for a second, but once the ball goes off the edge of the screen, the fun stops.
So the next step is to make the ball bounce off the edges of the screen,
Add this code and running the app will show a continuously bouncing ball.
Step 6. Creating Player Objects
Now it’s time to make the Player objects.
The first step in fleshing out the player class will be to make the move function change the position of the player. The side variable will indicate which side of the court the player will reside, which will dictate how to position the player horizontally. The y value, passed into the move function, will be how much up or down the player will move:
1: var Player = function (elementName, side) {
2: var position = [0,0];
3: var element = $('#'+elementName);
4: var move = function(y) {
5: }
6:return {
7: move: move,
8: getSide: function() { return side; },
9: getPosition: function() { return position; }
10: }
11: }
We can then lay out player movement, stopping the motion if the player sprite reaches the top or bottom of the window.
1: var move = function(y) {
2:// Adjust the player's position.
3: position[1] += y;
4:// If the player is off the edge of the screen, move it back.
5:if (position[1] <= 0) {
6: position[1] = 0;
7: }
The height of the player is 128 pixels, so stop it before any part of the player extends off the screen.
1:if (position[1] >= innerHeight - 128) {
2: position[1] = innerHeight - 128;
3: }
If the player is meant to stick to the right side, set the player position to the right edge of the screen.
1:if (side == 'right') {
2: position[0] = innerWidth - 128;
3: }
Finally, update the player's position on the page.
1: element.css('left', position[0] + 'px');
2: element.css('top', position[1] + 'px');
3: }
I can now create two players and have them move to their appropriate side of the screen:
1: player = Player('player', 'left');
2: player.move(0);
3: opponent = Player('opponent', 'right');
4: opponent.move(0);
So in theory you can move the player, but it won’t move without instruction. Add some controls to the player on the left.
You want two ways to control that player: using the keyboard (on PCs) and tapping the controls (on tablets and phones).
To ensure consistency between touch inputs and mouse inputs on various platforms, I’ll use the great unifying framework hand.minified there are others like https://github.com/jquery/PEP
First, I’ll add the script to HTML in the head section:
1:<script src="hand.js"></script>
I’ll then use Hand.js and jQuery to control the player when you press keyboard keys A and Z, or when you tap the controls.
In ping.css add the following at the top where you declare variables
1: var distance = 24;
Add the following section for controls
1: $(document).ready(function() {
2: lastUpdate = 0;
3: player = Player('player', 'left');
4: player.move(0);
5: opponent = Player('opponent', 'right');
6: opponent.move(0);
7: ball = Ball();
8:// pointerdown is the universal event for all types of pointers -- a
9: finger,
10:// a mouse, a stylus and so on.
11: $('#up') .bind("pointerdown", function() {player.move(-distance);});
12: $('#down') .bind("pointerdown", function() {player.move(distance);});
13: requestAnimationFrame(update);
14: });
15: $(document).keydown(function(event) {
16: var event = event || window.event;
This code converts the keyCode (a number) from the event to an uppercaseletter to make the switch statement easier to read.
1:switch(String.fromCharCode(event.keyCode).toUpperCase()) {
2:case'A':
3: player.move(-distance);
4:break;
5:case'Z':
6: player.move(distance);
7:break;
8: }
9:returnfalse;
10: });
Step 7. Adding Functions
As the ball bounces around, I want to let players catch it. When it’s caught, the ball has an owner, and it follows the motion of that owner. I’ll add functionality to the ball’s move method, allowing for an owner, which the ball will then follow:
If there is an owner, move the ball to match the owner's position.
1: function move(t) {
2:if (owner !== undefined) {
3: var ownerPosition = owner.getPosition();
4: position[1] = ownerPosition[1] + 64;
5:if (owner.getSide() == 'left') {
6: position[0] = ownerPosition[0] + owner.getsize();
7: } else {
8: position[0] = ownerPosition[0];
9: }
Otherwise, move the ball using physics. Note the horizontal bouncing has been removed -- ball should pass by a player if it isn't caught.
1: } else {
If the ball hits the top or bottom, reverse the vertical speed.
1:if (position[1]– halfTile <= 0 || position[1] + halfTile>=
2: innerHeight) {
3: velocity[1] = -velocity[1];
4: }
5: position[0] += velocity[0] * t;
6: position[1] += velocity[1] * t;
7: }
8: element.css('left', (position[0]– halfTile) + 'px');
9: element.css('top', (position[1]– halfTile) + 'px');
10: }
Currently, there’s no way to get the position of a Player object, so I’ll add the getPosition and getSide accessors to the Player object:
1:return {
2: move: move,
3: getSide: function() { return side; },
4: getPosition: function() { return position; }
5: }
Now, if the ball has an owner, it will follow that owner around. But how do I determine the owner? Somebody has to catch the ball. Let’s determine when one of the player sprites touches the ball. When that happens, I’ll set the owner of the ball to that player.
1: function update(t) {
First the motion of the ball is handled.
1:if(!paused) {
2: move(t);
3: }
The ball is under control of a player, no need to update.
1:if (owner !== undefined) {
2:return;
3: }
First, check if the ball is about to be grabbed by the player.
1: var playerPosition = player.getPosition();
2:if (position[0] <= 128 &&
3: position[1] >= playerPosition[1] &&
4: position[1] <= playerPosition[1] + 128) {
5: console.log("Grabbed by player!");
6: owner = player;
7: }
Then by the opponent...
1: var opponentPosition = opponent.getPosition();
2:if (position[0] >= innerWidth - 128 &&
3: position[1] >= opponentPosition[1] &&
4: position[1] <= opponentPosition[1] + 128) {
5: console.log("Grabbed by opponent!");
6: owner = opponent;
7: }
If you try playing the game now, you’ll find the ball bounces off the top of the screen, and you can move the player to catch it.
Now, how do you throw it?
That’s what the right-hand controls are for—aiming the ball.
Let’s add a “fire” function to the player, as well as an aim property.
Add supporting for Aiming
1: var aim = 0;
The fire function
1: var fire = function() {
Safety check: if the ball doesn't have an owner, don't not mess with it.
1:if (ball.getOwner() !== this) {
2:return;
3: }
4: var v = [0,0];
Depending on the side the player is on, different directions will be thrown.The ball should move at the same speed, regardless of direction -- with some math you can determine that moving .707 pixels on the x and y directions is the same speed as moving one pixel in just one direction.
1:if (side == 'left') {
2:switch(aim) {
3:case -1:
4: v = [.707, -.707];
5:break;
6:case 0:
7: v = [1,0];
8:break;
9:case 1:
10: v = [.707, .707];
11: }
12: } else {
13:switch(aim) {
14:case -1:
15: v = [-.707, -.707];
16:break;
17:case 0:
18: v = [-1,0];
19:break;
20:case 1:
21: v = [-.707, .707];
22: }
23: }
24: ball.setVelocity(v);
Release control of the ball.
1: ball.setOwner(undefined);
2: }
The rest of the Ball definition code goes here...
1:return {
2: move: move,
3: fire: fire,
4: getSide: function() { return side; },
5: setAim: function(a) { aim = a; },
6: getPosition: function() { return position; },
7: }
We can then augment the keyboard function to set the player’s aim and fire functions.
Aiming will work slightly differently. When the aiming key is released, the aim will return to straightforward.
1: $(document).keydown(function(event) {
2: var event = event || window.event;
3:switch(String.fromCharCode(event.keyCode).toUpperCase()) {
4:case'A':
5: player.move(-distance);
6:break;
7:case'Z':
8: player.move(distance);
9:break;
10:case'K':
11: player.setAim(-1);
12:break;
13:case'M':
14: player.setAim(1);
15:break;
16:case'':
17: player.fire();
18:break;
19: }
20:returnfalse;
21: });
22: $(document).keyup(function(event) {
23: var event = event || window.event;
24:switch(String.fromCharCode(event.keyCode).toUpperCase()) {
25:case'K':
26:case'M':
27: player.setAim(0);
28:break;
29: }
30:returnfalse;
31: });
The final addition will be touch support on all controls.
I’ll make the controls on the right change the aim of the player. I’ll also make it so touching anywhere on the screen fires the ball:
1: $('#left') .bind("pointerdown", function() {player.setAim(-1);});
2: $('#right') .bind("pointerdown", function() {player.setAim(1);});
3: $('#left') .bind("pointerup", function() {player.setAim(0);});
4: $('#right') .bind("pointerup", function() {player.setAim(0);});
5: $('body') .bind("pointerdown", function() {player.fire();});
Step 8. Keep Score
When the ball passes a player, I want to change the score and give the ball to that player. I’ll use custom events so I can separate scoring from any of the existing objects.
The update function is getting long, so I’ll add a new private function called checkScored:
1: function checkScored() {
2:if (position[0] <= 0) {
3: pause();
4: $(document).trigger('ping:opponentScored');
5: }
6:if (position[0] >= innerWidth) {
7: pause();
8: $(document).trigger('ping:playerScored');
9: }
10: }
The code below reacts to those events to update the score and hand over the ball. Add this code to the bottom of the JavaScript document.
1: $(document).on('ping:playerScored', function(e) {
2: console.log('player scored!');
3: score[0]++;
4: $('#playerScore').text(score[0]);
5: ball.setOwner(opponent);
6: ball.start();
7: });
8: $(document).on('ping:opponentScored', function(e) {
9: console.log('opponent scored!');
10: score[1]++;
11: $('#opponentScore').text(score[1]);
12: ball.setOwner(player);
13: ball.start();
14: });
Now when the ball makes it past your opponent (which isn’t that difficult, as the opponent doesn’t move) your score will go up, and the ball will be handed to the opponent. However, the opponent will just hold onto the ball.
Step 9. Adding an AI
You almost have a game.
The last step is adding the opponent with simple AI.
The opponent will try to stay parallel with the ball as it moves about. If the opponent catches the ball, it will move randomly and fire the ball in a random direction.
To make the AI feel a little more human, we will add delays in everything done.
The opponent AI has three possible states: following, aiming/shooting and waiting. I’ll be the state between following actions to add a more human element. Start with just that for the AI object:
1: function AI(playerToControl) {
2: var ctl = playerToControl;
3: var State = {
4: WAITING: 0,
5: FOLLOWING: 1,
6: AIMING: 2
7: }
8: var currentState = State.FOLLOWING;
9: }
Depending on the state of the AI, I’ll want it to do a different action. Just like the ball, I’ll make an update function I can call in requestAnimationFrame to have the AI act according to its state:
Do something to follow the ball.
1: function update() {
2:switch (currentState) {
3:case State.FOLLOWING:
Do something to wait.
1:break;
2:case State.WAITING:
Do Something to Aiming
1:break;
2:case State.AIMING:
3:break;
4: }
The FOLLOWING state is straightforward. The opponent moves in the vertical direction of the ball, and the AI transitions to the WAITING state to inject some slowed reaction time. The code below shows these two states:
1: function moveTowardsBall() {
2:// Move the same distance the player would move, to make it fair.
3:if(ball.getPosition()[1] >= ctl.getPosition()[1] + 64) {
4: ctl.move(distance);
5: } else {
6: ctl.move(-distance);
7: }
8: }
9: function update() {
10:switch (currentState) {
11:case State.FOLLOWING:
12: moveTowardsBall();
13: currentState = State.WAITING;
14:case State.WAITING:
15: setTimeout(function() {
16: currentState = State.FOLLOWING;
17: }, 400);
18:break;
19: }
20: }
21: }
The AI alternates between having to follow the ball and wait a split second. Now add the code to the game-wide update function:
1: function update(time) {
2: var t = time - lastUpdate;
3: lastUpdate = time;
4: ball.update(t);
5: ai.update();
6: requestAnimationFrame(update);
7: }
When you run the game, you’ll see the opponent follow the ball’s movements,
So thats a nice little AI in less than 30 lines of code.
Of course, if the opponent catches the ball, it won’t do anything.
So we now need to handle the actions for the AIMING state.
I want the AI to move randomly a few times and then fire the ball in a random direction. Let’s add a private function that does just that.
Adding the aimAndFire function to the AIMING case statement makes a fully functional AI against which to play.
1: function repeat(cb, cbFinal, interval, count) {
2: var timeout = function() {
3: repeat(cb, cbFinal, interval, count-1);
4: }
5:if (count <= 0) {
6: cbFinal();
7: } else {
8: cb();
9: setTimeout(function() {
10: repeat(cb, cbFinal, interval, count-1);
11: }, interval);
12: }
13: }
14: function aimAndFire() {
Repeat the motion action 5 to 10 times.
1: var numRepeats = Math.floor(5 + Math.random() \* 5);
2: function randomMove() {
3:if (Math.random() > .5) {
4: ctl.move(-distance);
5: } else {
6: ctl.move(distance);
7: }
8: }
9: function randomAimAndFire() {
10: var d = Math.floor( Math.random() \* 3 - 1 );
11: opponent.setAim(d);
12: opponent.fire();
Finally, set the state to FOLLOWING.
1: currentState = State.FOLLOWING;
2: }
3: repeat(randomMove, randomAimAndFire, 250, numRepeats);
4: }
Thanks you have completed the tutorial
All you need to do now is your publish your game to your Azure subscription.
Simply select Web site under the solution explorer right click and select publish
You can download the entire source to the project at https://github.com/leestott/Pong-Game---HTML-JS-Web-Game
Step 10. Testing your web site
This code is interoperable with modern browsers like Chrome, Firefox, and Microsoft Edge, it’s always a best practice to double-check.
You can do this easily with tools like http://www.browserstack.com and use a selection of free tools available at dev.modern.IE:
You can also scan your existing web sites and apps for out-of-date libraries, layout issues, and accessibility
And you can even now test you site Remotely for Microsoft Edge Support
Other Resources
There are loads of free great coding resources
Coding Lab on GitHub: Cross-browser testing and best practices
Hosted web apps and web platform innovations (from Kevin Hill and Kiril Seksenov including the manifold.JS project)
More free cross-platform tools & resources for the Web Platform:
Visual Studio Code for Linux, MacOS, and Windows
Code with node.JS and free trial on Azure
More advanced resources
Woah, I can test Edge & IE on a Mac & Linux! (from Rey Bango)
Advancing JavaScript without Breaking the Web (from Christian Heilmann)
The Edge Rendering Engine that makes the Web just work (from Jacob Rossi)
Unleash 3D rendering with WebGL (from David Catuhe including the vorlon.JS and babylonJS projects)