Aug 27

Learning JavaScript – Foundations

I’ve been working on a presentation summarizing the fundamentals of the JavaScript language for beginners. I figured I’d share it here for anyone interested.

Here is the direct link to the full Learning JavaScript – Foundations presentation on google slides.

Mar 22

A Pattern for handling concurrent edits to a MongoDB Document in Node.js

Lately I’ve been working on converting my space strategy game (Astriarch) to multiplayer using Node.js, Mongodb, and Mongoose.

One problem I faced while making the game multiplayer is handling concurrent edits to the mongo game documents. Here is the scenerio: two players decide to send ships (edit the document) at the same time. If we are lucky, there are no problems, however there is a chance that both players get the latest version of the document one after the other (before either one of them has time to save the document), then concurrently edit and save the document. What this means is that the last person to save the document wins, the first person’s edits are lost.

This problem can be handled in a couple of ways:

1. Change the model so that anytime there is the possibility of concurrent edits to the document, a new collection (or model) is created for each user’s edits, then at some point in the future those edits are merged into the document when it is guaranteed that only one process is modifying the document.
2. Use a nonce field in your document to protect against concurrent edits as described here.

The problem with option #1 is that it is more difficult to implement, it means making your model and processing more complicated, and you still need to guarantee that at some point you can safely merge in the changes to your document by ensuring only one thread/process is modifying the document at that time.

The key to option #2 is that a user will only be able to modify the document if the nonce field has not been changed since that user last fetched the document, this is done by providing the nonce within the update command.

models.PostModel.update({"_id":postId, "nonce":doc.nonce}, data, callback);

Depending on your application, if you are not able to update the document because someone else has updated it, you may simply want to return an error for the user with the latest document so that the user may choose to perform the edits and try to save again.

For my application, I wanted to make a generic function for handling concurrent edits to a mongo document, that way I could leverage this function in each context where edits to the document had to be made.

Here is a Github Gist of the “savePostByIdWithConcurrencyProtection” function and a sample of how it is used:

Notice how the savePostByIdWithConcurrencyProtection takes a transform function that it will execute to perform the actual work of the edit on the document object, and then handles the rest of the logic of performing the update while ensuring the nonce is used in the update as well as recursively retrying until some limit is reached.

You can see an example of how to use this function in the AppendPostText method where the transform function simply appends the text passed into the function to the document.

This pattern allows reuse of the same complex concurrent edit protection and retry logic in many different areas of my application.

Apr 23

Installing Node Modules through NPM

NPM is the Node Package Manager, it makes it easy to install external libraries and frameworks for use in your own projects. With NPM installed you can simply type:

npm install module-name

Upon running this command, npm will fetch that module from the repository and place it within the “node_modules” directory within your project. You can also install modules globally by adding the -g argument, installing a module globally places the code within the “node_modules” directory where the node binary is installed.

Steps to create your own public npm module

1. Create a new repository on github and clone it locally
2. Create a package.json file to describe your module
3. Create and Test the code for your module
4. Publish your module to NPM

Start creating your first NPM module

To create your own module, you’ll want to have a public repository on GitHub to house the source code. After cloning your new module repository to your local machine, run:

npm init

This will walk you through a set of prompts that allows you to specify details about your new module.

Most of these details are pretty obvious, and for many of the prompts you can just select the defaults. Entry point is the javascript file that will be invoked when consumers of your module “require” it, this file will include the main logic for your module, or if it is a large module you can export public functions found with other files (typically in the lib directory). After filling in the required information, a package.json file will be created with all the entered details

Create and Test the code for your module

Obviously, you’ll want your node module to do something useful, so start building out the functionality your module will provide. For my sample module, let’s say I want to make a function to calculate the distance between two points, my index.js file might look like this:

exports.dist = function(p1, p2){
return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
};

Next we can create a number of files to test the code we’ve created. For the dist function I’ve defined I can create a file to test it with the following code:

var myMod = require('./../index.js');
var p1 = {x:1, y:1};
var p2 = {x:4, y:5};
var dist1 = myMod.dist(p1, p2);
console.log("Distance between: ", p1, " and ", p2, " is:", dist1);

In the package.json file I specified the following command to run for the test script:

for f in tests/*; do echo "$f"; node "$f"; done; echo 'passed!'; exit 0

This command will be executed when I run:

npm test

Which should output something like this:

tests/test.js
Distance between:  { x: 1, y: 1 }  and  { x: 4, y: 5 }  is: 5
passed!

Now that you’ve written and tested the code for your node module, it’s time to publish it to the npm registry. Before you can publish your new module you’ll need to register a user on the npm website, or you can create a user with the adduser npm command. Finally you are ready to publish your module, simply issue the command:

npm publish

You will be prompted for the credentials for the user you just created and if all goes well, your module will be available for other to install using the npm install command:

npm install module-name

When making changes to your module you’ll have to update the version number in the package.json file and then reissue “npm publish” this will ensure users of your module can get the latest code.

Now that you’ve published your module you and others can leverage that useful code in other node projects!

Mar 23

The need for a Node Version Manager

Sometimes it is necessary to be able to quickly switch between versions of Node.js without having to uninstall and reinstall a new version. Perhaps one project is written for an older version of Node.js and works on that version, but you’d like to easily test it against a newer version of Node, or perhaps other projects you manage require a newer version of node and you need to be able to switch back and forth. There are two very good Node version management tools for this purpose: n and nvm, they work somewhat differently and each tool has its’ own advantages and disadvantages. I’ll be discussing these differences based on my experience using them on the Mac OS X platform, there will be minor differences in the paths on a linux distro like Ubuntu and for the Windows platform you’ll want to use other packages (nvmw or Nodist).

n vs. nvm



Now the fun stuff: The Water Bucket Logic Problem

Just choose your parameters using the sliders and click the calculate button, the code will determine the best solution, and then draw the steps out on the canvas for you:

Source Files

GraduatedCylinder.dart – The full Dart source code, or you can download all the code including the Dart editor project files in this: GraduatedCylinder-DartProject archive.

May 07

Stratiscape – A layered approach to HTML5 Canvas drawing

When I created my first HTML5 game I was surprised that the canvas element in HTML5 didn’t support multiple layers that could be painted on independently. Independent stacked layers would help in many situations when animating only a portion of a game (like the main character) so that the system doesn’t have to repaint backgrounds or other elements that remain mostly static. One way to get around this limitation is to have multiple stacked canvas elements that are painted independently and serve the same layered functionality I wanted. There are some canvas libraries that already support layers, but many of them were very heavy and added much more functionality than I needed for my game. That’s when I decided to build Stratiscape, a simple HTML5 layered canvas library.

Using the Stratiscape library is straightforward, it is a matter of creating an instance of the main Stratiscape class, defining one or more drawn objects for your canvases and then adding those objects to a stratiscape layer, and finally setting up the drawing interval. This article will show you how to build a simple animated stratiscape page, in the background we’ll draw a blue rectangle, and in the foreground we’ll have some circles that will bounce around inside the rectangle.

To create an object of the Stratiscape class, we pass in a config object that defines how we want the layers created:

document.stratiscapeDraw = new Stratiscape({'containerId':'canvasContainer',
'layers':[
{'name':'canvasBackground', x:0, y:0, width:640, height:480, 'backgroundColor':'black'},
{'name':'canvasForeground', x:0, y:0, width:640, height:480}
]
});


In our config object, one of the required properties is ‘containerId’ which should be the id of the element we want all of our generated canvas elements to reside, so we’ll want to make sure our page has a div with an id that we specified in our config object: “canvasContainer” like this:




Next let’s figure out what we want to draw and how we’ll draw it, to do this in Stratiscape, we define a subclass of the DrawnObject class and we should at least define two methods init and draw.

Here is a simple example of a “Rectangle” drawn object, the init function takes some position and size parameters as well as a couple of colors to use when we draw it.

Rectangle = Stratiscape.DrawnObject.extend({ //rectangle drawn object class

init: function(x, y, width, height, fillColor, strokeColor) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.fillColor = fillColor;
this.strokeColor = strokeColor;
},

draw: function(ctx) {

ctx.fillStyle = this.fillColor.toString();
ctx.strokeStyle = this.strokeColor.toString();
ctx.fillRect(this.x,this.y,this.width,this.height);
ctx.strokeRect(this.x,this.y,this.width,this.height);
}
});


Notice the draw method is passed a “ctx” object, which is the 2d context for the layer (canvas) that the Rectangle is a child of.

In order to make our stratiscape object actually draw, we’ll need to periodically call the main draw method on the stratiscape object like this:

window.setInterval(function() {stratiscapeDraw.draw() }, 1000 / 60);


Now all we have to add instances of our Rectangle Drawn Object to a layer of our stratiscape object and the library will take care of the rest.

document.stratiscapeDraw.getLayer('canvasBackground').addChild(new Rectangle(10, 20, 200, 150, "#369", "#FFF"));


The results of this are a bit uninteresting:

Let’s make our sample a bit more exciting and leverage the fact that we have two independent layers, lets make another class inheriting from drawn object, a circle:


Circle = Stratiscape.DrawnObject.extend({ //circle drawn object class

init: function(x, y, radius, fillColor, strokeColor, velocity, angle) {
this.x = x;
this.y = y;
this.fillColor = fillColor;
this.strokeColor = strokeColor;
this.velocity = velocity;
this.angle = angle;
},

draw: function(ctx) {

ctx.strokeStyle = this.strokeColor;
ctx.fillStyle = this.fillColor;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.closePath();
ctx.fill();
ctx.stroke();
}
});



Notice that we’ve given the circle class a velocity and angle, this is because we want to have our circles bouncing around our canvas layer. Let’s add an update method to the circle class that we’ll call repeatedly to change the circle’s location based on the angle and velocity.

    update: function() {
var offsetX = 0;
var offsetY = 0;
if(this.velocity != 0)
{
offsetX = this.velocity * Math.cos(this.angle * Math.PI/180);
offsetY = this.velocity * Math.sin(this.angle * Math.PI/180);
}

this.x -= offsetX;
this.y -= offsetY;

//check for collisions with our rectangle
if(this.x <= left) {
this.x = left;
this.angle += this.angle < 90 ? 90 : -90;
} else if(this.x >= right) {
this.x = right;
this.angle += this.angle > 180 ? 90 : -90;
} else if(this.y <= top) {
this.y = top;
this.angle += this.angle > 90 ? 90 : -90;
} else if(this.y >= bottom) {
this.y = bottom;
this.angle += this.angle > 270 ? 90 : -90;
}

if(this.velocity <= 0)
this.layer.removeChild(this);

if(this.angle > 360)
this.angle = this.angle%360;
if(this.angle < 0)
this.angle = 360 + this.angle;
},


Now all we have to do is add some of these circles to our foreground layer and setup our interval to call the update method on each circle.

document.canvasForeground = document.stratiscapeDraw.getLayer('canvasForeground');

for(var i = 9; i >= 0; i--)
{
var radius = (i + 1) * 5;
}

setInterval(function()
{
for(var i in document.canvasForeground.children)
{
document.canvasForeground.children[i].update();
}
document.canvasForeground.needsDisplay = true;//set "dirty" flag
}, 1000/30);


Notice that after calling the update method on each of the foreground layer's children, I need to set the "needsDisplay" flag to true on the canvas layer. This tells Stratiscape that changes have been made to the layer and that it must be re-drawn. Stratiscape will set the needsDisplay flag for you whenever adding or removing a drawn object from the layer, however, because we are just moving our objects around we must explicitly tell the layer that updates have been made and that it should re-draw itself on the next draw cycle. We could repaint a simple scene like this as often as we like and we would likely not see any performance degradation. However, for large, complex scenes where repainting might be more intensive, only drawing when objects have changed is an important optimization to make games and animation run smoothly.

Here is our full simple sample in action:

Checkout the other Stratiscape library samples and download the full source from github here:
Stratiscape - Layered Canvas Library

Apr 29

HTML5 Canvas Drawing Speed Testing using Stats.js and jsperf.com

Lately I’ve been doing some performance testing of different canvas drawing functions, I specifically wanted to test the performance of drawing radial gradients vs. arcs and images.

To facilitate my testing I used Stats.js – a graphical performance monitor you can easily add to your sites to test milliseconds between javascript calls and frames per second.

Another great resource for testing javascript performance is jsPerf.com, to create a test you simply add your setup and teardown code and then specify the code you want to test the performance of.

You can see my Canvas Draw Tests jsPerf, it gives you a nice graph of the historic runs by browser.

HTML5 Canvas Drawing Speed Tests

I’ve also included the code and test page I wrote here so you can try it out for yourself and tweak the test for your own needs if you like.

Sorry your browser doesn’t support the HTML5 canvas!

Results

I’m not done with my tests, I’d like to do further investigating and compare the performance of drawing paths and other shapes as well. At this point, it seems image drawing is across the board faster. I was actually surprised that in some browsers it seems that drawing radial gradients is faster than drawing a filled circle (arc). As I work on my next HTML5 game these performance testing methods will be helpful to figure out how to keep the game running at high frame rates. Another good resource for tricks to keep canvas drawing as fast as possible is the very good tutorial over at HTML5 Rocks: Improving HTML5 Canvas Performance.

Apr 10

Creating a Hex Grid for HTML5 Games in Javascript

In my last post, I described how to do some of the calculations for determining the required measurements to build a hexagon. Today I’ll show you how to take that a step further and build a hex grid or game-field out of those hexagons.

Let’s start with the overview and pseudo-code for populating our grid of hexes.

Overview/Pseudocode:

1. Populate each row while we have vertical space on the canvas
2. After each hex (column), increment the x direction by the width of the hex + the side length until we run out of horizontal space on the canvas
3. Every other row must be offset in the x direction by the width of the hex minus the side length divided by two
4. After each row increment the y direction by 1/2 the height of the hex

Simple version of JavaScript code:

HT.Grid = function(/*double*/ width, /*double*/ height) {

this.Hexes = [];

var row = 0;
var y = 0.0;
while (y + HT.Hexagon.Static.HEIGHT <= height)
{
var col = 0;
var offset = 0.0;
if (row % 2 == 1)
{
offset = (HT.Hexagon.Static.WIDTH - HT.Hexagon.Static.SIDE)/2 + HT.Hexagon.Static.SIDE;
col = 1;
}

var x = offset;
while (x + HT.Hexagon.Static.WIDTH <= width)
{
//first parameter of the hexagon constructor is the hexId
//   which we'll discuss more later
var h = new HT.Hexagon(null, x, y);
this.Hexes.push(h);

col+=2;
x += HT.Hexagon.Static.WIDTH + HT.Hexagon.Static.SIDE;
}
row++;
y += HT.Hexagon.Static.HEIGHT / 2;
}

};


That is pretty straight-forward, but before we have a usable grid we may want to add a few more things. If you notice my Hexagon constructor has an "Id" member, the purpose of the Id is to give each hex a unique string identifier, this makes it easy to reference each hex, either programmatically, or for debugging. I like to give my hexes a Letter prefix based on the row plus a number based on the column, but you can do whatever works for you.

Here is my simple function for getting the hex identifiers I want:


HT.Grid.Static = {Letters:'ABCDEFGHIJKLMNOPQRSTUVWXYZ'};

HT.Grid.prototype.GetHexId = function(row, col) {
var letterIndex = row;
var letters = "";
while(letterIndex > 25)
{
letters = HT.Grid.Static.Letters[letterIndex%26] + letters;
letterIndex -= 26;
}

return HT.Grid.Static.Letters[letterIndex] + letters + (col + 1);
};



Hex Distance:

Finally, since it is common in games to need to figure out the distance between two hexes, we probably want a function that takes two hexagons and returns a distance. To facilitate this, we'll need to assign some coordinates to each of our hexagons that will make it faster and easier to calculate distances when necessary. James McNeill has a very good post on his PlayTechs blog about hex grids where he describes a coordinate system for hex grids, and how to use that coordinate system to find distances between hexes.
Basically, instead of a coordinate system based on the rows and columns, we have columns (shown in green), and diagonal rows (shown in red). Once we have assigned coordinates to our hexagons as shown, we can use the following equation to calculate the distances between two hexes:
$\frac{|\Delta x| + |\Delta y| + |\Delta x - \Delta y|}{2}$

Here is my JavaScript function that returns the distance between two hexes in the grid:

HT.Grid.prototype.GetHexDistance = function(/*Hexagon*/ h1, /*Hexagon*/ h2) {
var deltaX = h1.PathCoOrdX - h2.PathCoOrdX;
var deltaY = h1.PathCoOrdY - h2.PathCoOrdY;
return ((Math.abs(deltaX) + Math.abs(deltaY) + Math.abs(deltaX - deltaY)) / 2);
};


Note: I'm using the PathCoOrdX and PathCoOrdY members of my Hexagons in the above function, which I populate in my full version of the Grid constructor, but I won't go into how I do that in this post, basically the PathCoOrdX comes from the column variable, and PathCoOrdY is populated in a second pass. You can download the full Grid.js code to see the exact method I use.

The Fun Part:

I've put together a simple form and canvas, similar to what I did in my last post, so that you can see the Hex Grid in action, and play with the parameters. I've also added another option that allows you to switch the hex orientation that you can play with.

Orientation:

Hex Based on Side Length

Side Length (z):

Ratio of Width:Height (4:3, r = 1.333), (2/√3, r = 1.1547...)

Hex Based on Width and Height

Width:

Height:

Source Files

Grid.js - The full source code for the grid class, or you can download all code for these Hexagon articles in this GitHub repo: HexagonTools.