Create a Basic Multiplayer Game in Phaser 3 with Socket.io – Part 1 (original) (raw)

In this multipart tutorial, we will be using Phaser 3 and Socket.io to create a simple multiplayer game. For our multiplayer game, we will follow the client-server game architecture. If you are not familiar with the client-server game architecture, the client is responsible for displaying the game to the player, handling the player’s input, and for communicating with the server. The server, on the other hand, is responsible for broadcasting that data to each client.

The goal of this tutorial is to teach you the basics of creating a multiplayer game. You will learn how to:

Need to explore some Phaser basics first? Try out Zenva’s Phaser Mini-Degree to learn how to make platforms, virtual pet games, RPGs, and more!

Course Files and Versions

You can download all of the files associated with the source code for part one here.

At the time this tutorial was written, the following versions were used. You may need to use these versions to have the same results from this tutorial.

CTA Small Image - Create a Basic Multiplayer Game in Phaser 3 with Socket.io - Part 1

FREE COURSES AT ZENVA

LEARN GAME DEVELOPMENT, PYTHON AND MORE

ACCESS FOR FREE

AVAILABLE FOR A LIMITED TIME ONLY

Tutorial Requirements

For this tutorial, we will be using Node.js and Express to create our server. We will also be using NPM to install the required packages we need for the server to run. In order to follow along with this tutorial, you will need to have Node.js and NPM installed locally, or you will need access to an environment that already has them installed. We will also be using the Command Prompt (Windows) / Terminal (Mac) to install the required packages, and to start/stop our Node server.

Having a prior experience with these tools is a plus, but it is not required for this tutorial. We will not be covering how to install these tools as the focus of this tutorial is making a game with Phaser. The last thing you will need is an IDE or Text Editor for editing your code.

To install Node.js, click the link here: and choose the LTS version. You can download and use the current version with this tutorial, however, the LTS version is recommended for most users. When you install Node.js, NPM will also be installed on your computer. Once you have these tools installed, you can move on to the next part.

Of course, you should also have some experience with Phaser. If this is your first time with Phaser, you can discover more Phaser basics with Zenva’s Phaser Mini-Degree learning pathway.

Setting up the server

The first thing we are going to do is create a basic Node.js server that will serve our game files. To get started, create a new folder on your computer, it can be called anything you want. Then navigate inside this folder and create a new file called server.js. Open up server.js and add the following code to it:

var express = require('express'); var app = express(); var server = require('http').Server(app);

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); });

server.listen(8081, function () { console.log(Listening on ${server.address().port}); });

In the code above we:

Before we can run the server, we will need to install the required modules for the server. Open your terminal/command prompt, and navigate to your project folder. Once there you will need to run the following command: npm init -f. This will create a package.json file in your project folder. We will use this file to keep track of all the packages that our project depends on.

Now, we will install express. In your terminal run the following command: npm install –save express. This will create a folder called node_modules in your project folder, and by adding the –save flag to the command, npm will save this package in our package.json file.

Setting up the client

With the basic server code finished, we will now work on setting up our client-side code. In your project folder, create a new folder called public. Any file we put in this folder will be rendered by the server that we set up. So we will want to put all of our static client-side files in this folder. Now inside the public folder, create a new file called index.html. Open up index.html and add the following code to it:

<head>
    <meta charset="utf-8">
</head>

<body>
    <script src="//cdn.jsdelivr.net/npm/[[email protected]](/cdn-cgi/l/email-protection)/dist/phaser.min.js"></script>
    <script src="js/game.js"></script>
</body>

In the code above, we set up a simple HTML page and we referenced two JavaScript files, phaser.min.js (the phaser game framework) and game.js (our Phaser game code). Back in the public folder, create a new folder called js , and in this folder create a new file called game.js. Open up game.js and add the following code to it:

var config = { type: Phaser.AUTO, parent: 'phaser-example', width: 800, height: 600, physics: { default: 'arcade', arcade: { debug: false, gravity: { y: 0 } } }, scene: { preload: preload, create: create, update: update } };

var game = new Phaser.Game(config);

function preload() {}

function create() {}

function update() {}

Let’s review the code we just added:

With our basic client-side code setup, we will now test our server and make sure everything is working correctly. Back in the terminal/command prompt, run the following command: node server.js and you should see the following line appear Listening on 8081. Now, if you open up your web browser and navigate to http://localhost:8081/, you should see a black box on the web page, and if you open the console in the developer tools, you should see a log with the version of Phaser your game is running.

Blank Phaser 3 game running in Google Chrome

Adding Socket.IO

With our server now rendering our game, we will now work on adding Socket.IO to our game. If you are not familiar with Socket.IO, it is a JavaScript library that enables real-time, bi-directional communication between web clients and servers. To use Socket.IO, we need to update our client and server code to enable the communication between the two.

Back in your terminal, run the following command: npm install –save socket.io. If your server is still running, you can either: open a new terminal window and run the code in your project folder, or stop the server (CTRL + C) and then run the command. This will install the Socket.IO node package and save it in our package.json file.

Now, in server.js add the following code below the var server = require(‘http’).Server(app); line:

var io = require('socket.io').listen(server);

Then add the following code above the server.listen line:

io.on('connection', function (socket) { console.log('a user connected'); socket.on('disconnect', function () { console.log('user disconnected'); }); });

In the code above we:

Next, we will update the client side code to include the Socket.IO library. Open up index.html and add the following line at the top of the element:

Then, open up game.js and add the following line inside the create function:

this.socket = io();

Now, if you start the server back up again, and refresh your game in your browser, you should see the user connected/disconnected messages in your terminal.

Console information denoting users connecting and disconnecting

Adding players – Server

Now that we have our socket connections setup, we can move on to adding players to our game. In order to keep all of the player’s games in sync, we will need to notify all players when a user connects or disconnects from the game. Also, when a new player connects we will need a way to let the player know of all the other players in the game. To do all of this we will need to store some player data, and we will use the socket connections to send messages to our players.

For this tutorial, we will store the player data in memory on the server. Normally, we would want to store this data in some type of database, that way it would be persistent, and if the server fails, we could easily recover the state of the game.

In server.js add the following line below the io variable:

var players = {};

We will use this object to keep track of all the players that are currently in the game. Next, in the callback function of the socket.io connection event add the following code below the console.log(‘a user connected’); line:

// create a new player and add it to our players object players[socket.id] = { rotation: 0, x: Math.floor(Math.random() * 700) + 50, y: Math.floor(Math.random() * 500) + 50, playerId: socket.id, team: (Math.floor(Math.random() * 2) == 0) ? 'red' : 'blue' }; // send the players object to the new player socket.emit('currentPlayers', players); // update all other players of the new player socket.broadcast.emit('newPlayer', players[socket.id]);

Let’s review the code we just added:

When a player disconnects, we need to remove that player’s data from our players object, and we need to emit a message to all other players about this user leaving, that way we can remove that player’s sprite from the game.

In the callback function of the socket.io disconnect event add the following code below the console.log(‘user disconnected’); line:

// remove this player from our players object delete players[socket.id]; // emit a message to all players to remove this player io.emit('disconnect', socket.id);

Your server.js file should look like the following:

var express = require('express'); var app = express(); var server = require('http').Server(app); var io = require('socket.io').listen(server);

var players = {};

app.use(express.static(__dirname + '/public'));

app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); });

io.on('connection', function (socket) { console.log('a user connected'); // create a new player and add it to our players object players[socket.id] = { rotation: 0, x: Math.floor(Math.random() * 700) + 50, y: Math.floor(Math.random() * 500) + 50, playerId: socket.id, team: (Math.floor(Math.random() * 2) == 0) ? 'red' : 'blue' }; // send the players object to the new player socket.emit('currentPlayers', players); // update all other players of the new player socket.broadcast.emit('newPlayer', players[socket.id]);

// when a player disconnects, remove them from our players object socket.on('disconnect', function () { console.log('user disconnected'); // remove this player from our players object delete players[socket.id]; // emit a message to all players to remove this player io.emit('disconnect', socket.id); }); });

server.listen(8081, function () { console.log(Listening on ${server.address().port}); });

Conclusion

With our server code for adding players in place, this brings part one of this tutorial to an end. In part two we wrap up our multiplayer game by:

I hoped you enjoyed part one of this tutorial and found it helpful.

Note that if you feel a bit out of depth, don’t be afraid to explore some basic web development courses first for individuals or explore Phaser courses focused on basic Phaser mechanics and usage.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

Python Blog Image - Create a Basic Multiplayer Game in Phaser 3 with Socket.io - Part 1