Easy Networked Games with sim-sim-js

A long while ago, I wrote a simultaneous simulation networking library to simplify making multiplayer games in Ruby. Dave Crosby later made a port of the library, called sim-sim-js, for JavaScript, making it much easier to create real-time multiplayer games in the browser.

This short tutorial will show you how to get started making awesome networked games in the browser with sim-sim-js. Before we get started, note that you’ll need Node.js for the server and for npm, to install some dependencies.

Installing Packages

To get started, create a directory for your project and run the following:


npm install sim-sim-js --save
npm install socket.io --save
npm install express --save

Those will install sim-sim-js and supporting socket libraries in the current directory. sim-sim-js is designed to be flexible with regard to how the actual networking communication is performed, but it has a build in adapter for Socket.IO, so it’s definitely easiest to start with that.

Setting Up a Server

A basic setup for a server looks like this:


var port = Number(process.env.PORT || 4050)

var simSim = require('sim-sim-js');

var express    = require('express');
var expressApp = express();
var httpServer = require('http').createServer(expressApp);
var socketIO   = require('socket.io').listen(httpServer, {log: true, secure: false});

var simultSimServer = simSim.create.socketIOServer({
    socketIO: socketIO,
    period: 50,
    logging: {
      debug: true,
      incomingMessages: true,
      outgoingMessages: true,
      suppressTurnMessages: true, }
    });

httpServer.listen(port);

Save it in a file called server.js.

One of the advantages with the simultaneous simulation approach to networked games is that the server is almost completely generic. The above server setup should work without changes for most games.

Then you can start the server with node server.js.

Setting Up a Client

The client side is a little more tricky.

In your client .html file, you’ll need to add some script tags to pull in sim_sim.js and socket.io.


Creating a World

When creating an approprate world object, it’s helpful to look at some examples. I’ve created a minimal example here. You’ll need to create a world object that holds all the game state that needs to be synchronized and supports the following methods:

  • .getData()
    This should return an object containing all the data in the world.

  • .setData(data)
    This does the oposite of getData(). Given an object containing all the data in the world, it updates the world with this data.

  • .getChecksum()
    This should return some checksum of the game state. It’s used to verify that all of the clients are properly synchronised. But for getting started quickly, or for testing, you can just return 0.

  • .playerJoined(id)
    This is called when a new player joins the simulation. You should create any “player” objects here.

  • .playerLeft(id)
    This is called when a player leaves the simulation.

  • .incomingEvent(id, event)
    This is called for any events sent to the simulation with sendEvent(). The id is the id of the player who sent the event.

  • .step(dt)
    This is called to step the simulation forward dt amount of time. This is where you should update your world to move players, fire missiles, etc…

  • .theEnd()
    This is called when the simulation ends. You don’t have to do anything here if you don’t want to.

Starting a Simulation

Once you have a world object defined, you can create and start a simulation like this:


// Create world
var world = new MyWorld();

// Create a simulation (with your world) and point at server
var sim = SimSim.createSimulation({
    adapter: {
        type: 'socket_io',
        options: { url: "http://localhost:4050" }
    },
    world: world
});

// Start simulation (connections happen here)
sim.start();

Updating the Simulation

Once you have your world set up and your simulation started, you need to keep your simulation updated by calling update(). It’s best to do this at least once a frame, but it doesn’t hurt to call it more often. Update needs to be past the current “time” in seconds. Something like this:


    sim.update(window.performance.now() / 1000);

To interact with your simulation, you send it events like this:


    sim.sendEvent(myEvents);

The event will eventually show up in your incomingEvent handler on your world object. But it will be carefully synchronized behind the scenes with all the other players, or participants in the simulation.

Hope you enjoy exploring this method and have fun!