Ben Nolan

Canvas game

Simon Willison said that he thought it wouldn't be long until someone made a MMO in Javascript using the canvas tag - and it's been something that stuck in my head. Last night I did a bit of playing around and came up with the basic framework for a minimal real time strategy game in pure javascript.

This is the first prototype of the idea. The thing on the left that looks like a pie chart is a Hatchery, it spawns blobs that go and eat the fungis. I'm thinking of building a minimal RTS based upon the Zerg class of Starcraft.

Technology

  • Jquery for event normalization
  • Underscore.js for enumeration mixins (.map, .reduce, etc...)
  • Canvas for drawing everything

Challenges

The movement logic and drawing logic have to be seperated, so that eventually all the logic can run on a node.js server, and just send a json update of each of the blobs state every 300ms. In the meantime, the web browser has to be able to move and draw the blobs every 30ms. I have decided to do this by having a base class that handles:

  • Position
  • Motion vector
  • Spatial lookups

The spatial lookups are particularly interesting - because the logic loop of the game is O(N^2) complexity where N is the number of blobs in the game, and it involves many distance calculations (each with a square root). These spatial lookups can be significantly sped up by using a two dimensional tree acceleration structure. My goal is to create a module for node.js that reimplements the slow parts of the base class in performant C++ if I get to the stage where the server can't handle all the game logic.

The new canvas game

I was looking at the state of the art (WPilot) and decided to have a go at building a space simulator.

Thus - my Experiment #2. My goals here were:

  • Create obstacles that the player can't move through
  • Create non tile-based obstacles
  • Do a little math and use my vector library

I was inspired by the classic C64 game Exile when I created this - I loved the atmosphere of that game. Thoughts from this:

  • Javascript is very well suited to doing RPG-ish games
  • Latency is too high (using current tech) for real time battles
  • The canvas and javascript engine in safari / firefox is very capable

My next goal is to learn some more about common.js and move some of my classes (the vector and boundingbox classes) onto github.

Common JS

I've been working on a top sekret project using jquery and a few html 5 technologies. I'm using aspect-oriented programming to create my classes, and as with all projects - it gets to the size where I want some more order and architecture. I've been investigating commonjs since I already use it on the server side (with node.js).

About common js

Common js is a specification for creating reusable javascript modules, how those modules should expose themselves and how dependencies should be handled. It's a simple and easily implementable system. Who knows if it's perfect - but it's simple and a standard, so I'm trying it out.

My current plan is convert my massive application.js into several different classes. Each class will need jquery to be present, but otherwise all dependencies should be explicit. I will use a runtime loader for my edit/refresh development, but I intend to have a preprocessor step to create one massive javascript file for deploying to production.

The observable patten

I haven't tested this yet - but this observable pattern looks like a lovely way to do observers and emitters...

I'll try to make some more notes as I learn more.

A new blog

I've followed in the style of Sam Minnee and converted my blog to a git deployed roll-your-own solution. I put in a bit of css3 (via LESS) and glued it together with a few lines of php.

Vector class

This vector class might be useful to some people. It supports chaining so you can do stuff like:

var v1 = new Vector(100,200);

console.log(v1.subtract(new Vector(200,300)).normalize().inverse().toString());

The class:

var Vector = function(x,y){
    this.x = x;
    this.y = y;

    this.subtract = function(v){
        return new Vector(this.x - v.x, this.y - v.y);
    }

    this.add = function(v){
        return new Vector(this.x + v.x, this.y + v.y);
    }

    this.normalize = function(){
        var length = this.length();
        return new Vector(this.x / length, this.y / length);
    }

    this.length = function(){
        return Math.sqrt(this.x*this.x + this.y*this.y);
    }

    this.toString = function(){
        return "Vector(" + [this.x, this.y].join(", ") + ")";
    }

    this.inverse = function(){
        return new Vector(-this.x, -this.y);
    }

    this.distanceTo = function(v){
        return this.subtract(v).length();
    }
}

The Nolan Mix-in

This is how I do my mixins. It is aspect oriented and doesn't require any external libraries. I tend to use it instead of prototype based, or base2-style inheritance. Mixins are dirty but hey - all of javascript is dirty, so why not embrace the grunge!

An example mixin class:

var Observable = function(self){
    var observers = {};

    self.observe = function(e, func){
        if(!observers[e]){
            observers[e] = [];
        }

        observers[e].push(func);
    }

    self.emit = function(e, arg){
        if(observers[e]){
            observers[e].forEach(function(func){
                func(arg);
            });
        }
    }
}

How to use the mixin:

var Widget = function(){
  new Observable(this);

  function poke(){
    emit('poked');
  }
}

widget = new Widget;
widget.observe('poked', function(){
  alert("!");
})
widget.poke();

I've been using this pattern for several months now. Some of the features:

  • Doesn't require external libraries, it's a pattern not some code
  • Aspect oriented (so you can hide internal variables)
  • Easy to understand
  • Works like a proper mixin, it's not multiple inheritance

Things missing:

  • You can't check whether an instance of a class contains a mixin, but that'd be easy enough to add if that was important to you.