Developing a WebGL Game – Part 2 (keeping JavaScript organized)

JavaScript has a tendency to get messy pretty quickly (and I’m pretty sure this isn’t just when I am writing it!).

This is due in my opinion to a number of factors:

  • People don’t understand the language and which can mean they get caught by a few traps (e.g. clobbering global scope)
  • Dev’s are unaware of some of the facilities available to them to write cleaner code (e.g. functional scope which I guess can also trip a few people up)
  • There is currently no inbuilt support for classes, modules/namespaces or script loaders. Of course there are a number of third party libraries to assist with this & some of these areas may well available in EcmaScript vNext
  • Having to cope with browser differences
  • Development & re-factoring tool’s probably aren’t quite as mature as those used in compiled languages
  • A lot of peoples JS experience is to add a pop up alert box when validation fails or to bring in a jQuery widget

In my WebGL game there is likely to be a fair amount of JavaScript so we will need to keep things organized otherwise it’s going to be as much fun working with as Sql Server Reporting Services – yes that bad my friend..

So how to organize our code?

Below is a screenshot of my current script setup (excluding external libraries).

Screenshot of scripts within game

In the beginning much of the code was in three or so files until it became obvious it needed to be pulled apart. As the game has developed I have constantly been re factoring and pulling the code out into separate files as needed and this has worked well allowing me to develop the game rapidly without getting caught up in architectural decisions.

The file Game.js contains a number of three.js specific concepts such as the game scene, camera, lighting and rendering loop.

Some of the scripts are pretty small but that’s the way I like them – much easier to maintain & anyway they will all be concatenated and bundled together before being served to the user.

Below is some code that sends a command (e.g. move creature from A to B) using SignalR proxy – it does one thing and it does it well (although er it prob should have some error handling but let’s move along):

var GameCommandSender = (function() {

"use strict";

function send(command) {

Game.eventBus.server.sendCommand(command);

}

return {

send: send

};

})();

Module pattern

This brings us to a common pattern in JavaScript for organizing code, the module pattern.

In its simplest state (and there are a number of variations each with their own advantages) the module pattern looks like this:


var myModule= (function () {

//just visible inside our function
var myPrivateValue=1;

//visible outside function

var myPublicValue=2;

function myFunction{
}

//lets export what we want people to use
return {
myFunction: myFunction,

myPublicValue: myPublicValue
}
}());

The module pattern allows us to encapsulate functionality within the myModule variable & hide variables and functions we don’t want to expose.

Strict mode

The one addition I would suggest you be sure to make in your modules is to turn on JavaScript’s strict mode by adding the following declaration to the start of your function:

“use strict”

This will help catch all sorts of things you probably didn’t want to do anyway such as accidentally creating a new variable on global scope – if you want to know more about strict mode & other EcmaScript 5 features checkout my EcmaScript 5 presentation in the downloads section of my website.

You can if you wanted turn on strict mode everywhere by declaring it in global scope but weird things might happen if you are using 3rd party libraries that don’t expect Strict Mode to be on so I would keep to declaring it inside your functions for now.

Missing classes & inheritance

With game development I have really missed having OOP constructs such as classes & inheritance easily available.

You can to simulate classes and inheritance in JavaScript but it’s slightly different to what you may be used to.

For example for any command (a message that is sent from client to the server) whether it is a move creature or attack I always want to know the type of command, which game session a player belongs to and the player making the command.

For this common functionality it makes sense to have a base command “class”:


function command(type, gameGroupName, gamePlayerId) {

this.type = type;

this.gameGroupName = gameGroupName;

this.gamePlayerId = gamePlayerId;

}

command.prototype = {

send: function() {

GameCommandSender.send({

type: this.type,

data: this.data,

gameGroupName: this.gameGroupName,

gamePlayerId: this.gamePlayerId

});

}

};

We can then inherit the command “class” using prototypical inheritance and add on functionality specific to our move command:

function moveCommand(creatureInstanceId, gameColumn, gameRow) {

this.data = {

creatureInstanceId: creatureInstanceId,

gameColumn: gameColumn,

gameRow: gameRow

};

}

moveCommand.prototype = new command('Move', gameGroupName, gamePlayerId);

moveCommand.prototype.constructor = moveCommand;

I think in the future I’ll be re-writing some of this in TypeScript. TypeScript offers a neat shorthand for classes, inheritance & interfaces and can help catch stupid errors like typos & vartiable type assignments but for now it will do.

If you want to know more about the module pattern, inheritance and many other patterns Addy Osmani has a great list of patterns and Stoyan Stefanov has a very detailed book that is a good reference.

That’s all for now 🙂

Advertisements