The right tools for the job: Socket.io & Node.js

More than a render engine, there is one dependency we critically need: something to handle the network connection! This is expertly handled by two powerful libraries called Socket.io and Node.js.

Socket.io helps us connect to other computers over a socket. It also aids with messaging and events on that socket.

Node.js is a very large and diverse library for building network applications. Through the node package manager, we can install additional frameworks that build upon Node.js.

Here, we particularly need Express, which is a framework for web applications.

With these powerful tools, a working network application is not far away!

In the Network folder of the Examples repo, you can find an example of one such application; a simple chat application.

To test the example, you will need to install Node.js. Then, follow the instructions in the README.txt file.

The right tools for the job: PIXI.js

In order for this project to be able to focus on the network multi-player development, we will need strong dependancies that can deal with other aspects of a game. One such aspect it graphics, and to handle it, I have selected PIXI.js.

PIXI.js is a complete render engine for HTML and javascript. It supports webGL, but will automatically revert to drawing on the regular canvas if we find ourself in a context that doesn’t support webGL. It is very fast and has lot’s useful tools and features. What else could we ask for?

Getting started with PIXI.js is extremly simple, check out this snippet:

// Get the renderer
var renderer = PIXI.autoDetectRenderer(640, 480);

// ...and append it to the document
document.body.appendChild(renderer.view);

// Create stage
var stage = new PIXI.Stage(0x000000);

// Create sprite
var sprite = new PIXI.Sprite(PIXI.Texture.fromImage("simple.bmp"));

// ...and add it to the stage
stage.addChild(sprite);

function paint() {
	// Request that we paint again when the browser does
	requestAnimFrame(paint);

	// Render the stage
	renderer.render(stage);
}

// Paint the first frame!
paint();

This will create a single sprite and render it each frame. The stage is the parent to all sprites and also serves as a solid color background.

Objectivity

The design of game objects is a very important part of Ophelia. We need objects that fulfill a lot of different specifications. Let us look at these, one at a time and see how the design of Ophelia will deal with them.

We will start with one of the most important:

“Objects need to be able to synchronize their internal state with their clones on other connected clients without demanding additional work from the developer who is creating an application with the engine.”

This looks tricky at first. When coding the behavior of their objects, developers are bound to modify the internal state of the object constantly. How can we detect this change? We could test if anything has changed, but the cost of doing this would quickly add up as more objects, or properties of objects, are  added to the game. We could demand that users only modify the state of objects in response to certain events and then we can just test which properties that changed after this event. But now we have begun to restrict the user, which we didn’t want to do.

Luckily, javascript comes to the rescue. Instead of defining our objects’ state with regular properties, we can define them with the defineProperty() method. This allows us to create custom setters and getters for the properties, while retaining the same interface.

In the example below, we store the actual value of these properties inside a private member object, to ensure that they cannot be accessed directly.
Of course, our setter could contain any code we want. This is the place where we will handle object synchronization.

function GameObject(){

   var properties = {};

   this.addProperty= function(name, initialValue){

      properties[name] = initialValue;

      Object.defineProperty(this, name, {

         configureable : true,

         enumerable : true,

         get : function(){
            return properties[name];
         },

         set : function(value){
            properties[name] = value;
         }
      });
   }
};

For a functioning example for how this can be used, look at the Object Properties example in the Examples repo.

In the beginning…

When creating an online multi-player game, one has to consider many things. Different clients need to be able to communicate with each other and with the server. Objects have to be synchronized so that all players get to see the same things. Messages have to be sent across the network and managed on all ends.

But where to begin? For an inexperienced developer, especially, it can be easy to get lost in the code. And even one little problem with synchronization or messaging will begin to add up, causing clients to more and more out of sync.

This project is about providing a solution to this. What if we could create a framework that allowed us to develop games with the same ease we make games for a single player, with the multi-player addition being as easy as setting the number of players to two.

But it is possible? Check back later to find out more.

You can look at the progress and eventual result of the project by taking a peek in the repository, from the link in the sidebar.