Chronicles of the Development of a Multiplayer Game: Part 3 — Your Turn.

Gary Weiss
Javascript Multiplayer GameDev
6 min readMar 7, 2017

This is the third and final part of a series on multiplayer game development in JavaScript. You may want to read Part I and Part II. This post provides some guiding concepts for anyone who would like to develop their own multiplayer game in JavaScript. It also introduces Lance.gg, an open-source library we developed as part of this process.

I won’t be offended if you fork it. The code is available here.

I think the death star is just around that corner!

Before You Start

So you want to embark on a fantastic journey, and develop your own multiplayer game in JavaScript? cool. As you get started, you’ll need to stop at three major junctions. First, understand your game’s requirements; second, learn about the game architectures used in existing multiplayer games; and last, develop an architecture that will meet the requirements of your game.

Next, pour 250 milliliters of “multiplayer” hydrate (source: Flickr)

Understanding Your Game’s Requirements

I want to take a step back for a moment, and talk about game requirements. In the development of spaaace, we needed to understand exactly what type of game we were developing. Otherwise, we wouldn’t have gotten very far. You can play the game online, there is a game server running in Europe, and another one in the United States.

Different networked game types rely on substantially different network architecture implementations. Are you building a first-person shooter? A real-time strategy game? A car racing game? A massive multiplayer online game? All of these categories have substantially different requirements which lead to different preferred implementations.

In our case we needed to implement a game where many miniature spaceships fly around and shoot at each other. We wanted to be able to support hundreds of spaceships.

Here is a list of five questions, which I think are useful to anyone embarking on the development of a multiplayer game. They are meant to help categorize the requirements. Each question is followed by the answer that we reached while developing the spaaace game.

  1. Does the game need a full-featured physics engine, or can it use simplified pseudo physics?
    A real physics engine was not strictly required in our game, since there was no gravity or constraints. We only needed to calculate positions based on velocity and orientation angle. If your game needs constraints or has many walls to bounce around, then you may need a proper physics engine like cannon.js.
  2. Are the positions of the game objects discrete or continuous?
    For spaaace, the positions are continuous floating-point numbers. But in some games, for example real-time strategy games, the positions are discrete. If the game objects can be positioned on an invisible grid, then their positions are discrete.
  3. How many objects will be broadcast at any given time?
    For us, about one thousand, including the missiles. Note that the question refers to networked objects. For example, your game may have several cars, and each car may include four wheels and other sub-components — but if it’s possible — try to broadcast each car as a single entity.
  4. Does the visual response need to be faster than typical online ping time of 150 ms?
    This is a tricky requirement, and unfortunately for us the answer is yes. However many games were able to bypass this requirement using ingenious visual effects. For example, if the user presses the accelerate button, consider showing a glowing afterburner for 100ms before actually moving the ship. Or hurrying the initial acceleration on the server to “catch up” to where the client is at.
  5. Do the game mechanics follow a deterministic process?
    This question is very important, because a deterministic game means that all clients have the ability to re-create the exact same game state given the exact same user inputs at each step. That means that clients can send inputs to each other, and skip the hop to the server. That’s very tempting. Very tempting indeed. But unless you really know what you’re doing, you will probably have to answer NO to this question. Deterministic game engines need to use a fixed-point math library to ensure all calculations results are deterministic.
Old-School non-deterministic game (source: Flicker)

Game Architecture

There are many alternatives that one can choose for a game’s architecture. For example there is lock step, interpolation, extrapolation, as well as peer-to-peer variants. Unfortunately it is out of the scope of this post to describe these architectures, but it is crucial for game developers to understand these alternatives and learn about which were used in well-known multiplayer games. You can read about these alternatives in the reading resources provided below.

In our case, given the answers above, the appropriate architecture for spaaace requires client-side prediction, and a simplified physics engine. It is feasible to send both inputs and object positions over the network because we don’t have that many. The game loop can be a fast 60Hz, because we are using simplified physics, so each step executes well under 16ms; the server state broadcast frequency can be high as well, because only a few kilobytes are sent in each broadcast, so I chose 10Hz; lastly, the render loop frequency is not up to us, it is decided by the browser’s tyrannical requestAnimationFrame().

The major components in our architecture are:

  • Game Logic Code. Process user inputs on each spaceship, turning the spaceships, accelerating, and firing missiles. Detecting collisions (kills). This code needs to be able to run on the server, but also on the client in the client-prediction mode.
  • Visuals. Draw the ships and missiles, sounds, show acceleration thrust, camera control, keyboard inputs, game visuals on connection and start.
  • Client-Side Prediction Infrastructure. This is a big one. And needs to be game-agnostic. It needs to run the game logic on the server, send periodic broadcasts to the clients, and implement the client-side prediction which shows each client extrapolated positions — until actual positions arrive from the server on the next broadcast.
  • Server and Client Setup Code, which connect the pieces together, starting the game, connecting the clients, keeping track of score, etc.

A New Multiplayer Synchronization Library: Lance

The game architecture we implemented in spaaace is based on the principle of separation of concerns. We wanted to isolate the code which is specific to our game, from the code which could be used by other multiplayer JavaScript games. This fundamental rule is what led us to create Lance, a game-agnostic multiplayer server. Much of the work we did resulted in extended functionality in Lance.

Your car is ready, Mr. Bond. (source: Flickr)

We released Lance as an open source library, so I hope that it will be of use to other game developers. Currently, Lance implements many features like client-side prediction, client-server communication, serialization of objects, step drift handling, and support for physics engines. There is more planned down the road. Learn more about it at: http://Lance.gg

Literature on Multiplayer Games and Physics

Other Resources

The development stack we used in spaaace was: nodejs, socket.io, WebPack packager, es6 language support, PixiJS, and Lance.

This might come in useful too:

Pouring a cup of freshly-brewed multiplayer premium roast (source: pexels)

Conclusion

Here are my parting words on the topic of JavaScript multiplayer programming. It works just fine. You can choose to build your own infrastructure with socket.io, and maybe try to go even further with WebRTC and give P2P communication a go. Better yet, http://Lance.gg may give you the infrastructure you need, allowing you to spend more time on the important stuff.

The development will be time consuming, especially for long-running game-worlds or for games which have sensitive timing requirements. Give proper consideration to the option of altering your original game concept or camera position if it helps solve a problem related to networked game play. Have patience. Wear sunscreen.

--

--