Skip to content

Using PlayCanvas with MassiveRealm

PlayCanvas is a popular open-source 3D game engine for the web.

You can use MassiveRealm with PlayCanvas to create multiplayer games.

Getting started

Check out our Quick Start Guide to create a new MassiveRealm project and get your API key.

Prerequisites:

  • Create a new MassiveRealm project.
  • Your project's URL and Public Key will be sent to your email.
  • Create Logic entry.
  • Create Room entry with alias game.

MassiveRealm Server Setup

This demo demonstrates multiplayer implementation with MassiveRealm.

Try the demo:
https://playcanv.as/p/jgHYeDcY/

Client-side source code:
https://playcanvas.com/project/1204880/overview/multiplayer-with-massiverealm

Server-side:
https://console.massiverealm.com/account/project/4094-e43c-4dbf

Step 1: Create Model

Navigate to the Communication > Models section in your project's logic and create a new model called Player with the following fields:

  • id - String
  • x - Float64
  • y - Float64

Model: Player

Step 2: Create Server Command

Navigate to the Communication > Server section in your project's logic.

Create a new command called UpdatePosition with the following input parameters:

  • x - Float64
  • z - Float64

This command will be called by the client to update the player's position.

Server: Update

Add the following code to broadcast the player's position to all clients.

We're using cluster: true to broadcast the message across all locations in the Massive Cluster

javascript
let data = {
    id: $session.id,
    x: $params.x,
    z: $params.z
};

// Use cluster=true to broadcast message across all locations
$session.broadcast(
    'UpdatePlayer',
    {
        player: data
    },
    {
        cluster: true
    }
);

Server: Update

Step 3: Create Client Commands

Navigate to the Communication > Client section in your project's logic. Here we will create 2 commands:

Command 1: UpdatePlayers

Input Parameters:

  • players - Type: "Model: Player"

Client: UpdatePlayers

Command 2: DeletePlayer

Input Parameters:

  • id - String

Client: DeletePlayer

Step 4: Hooks

Navigate to the Communication > Hooks section in your project's logic.

Hook 1: OnRoomLeave

Broadcast a message to all clients when a player leaves the room.

We're using cluster: true to broadcast the message across all locations in the Massive Cluster

javascript
$room.broadcast(
    'DeletePlayer',
    {
        id: $session.id
    },
    {
        cluster: true
    }
);

Hooks: OnRoomLeave

PlayCanvas Client Setup

Connect MassiveRealm Script

Like this:PlayCanvas - External Script

Networking Script

Create a new script in your PlayCanvas project called Networking.js.

Here is the example code:

javascript
var Networking = pc.createScript('Networking');

Networking.attributes.add('accessPointUrl', {
    type: 'string',
    title: 'Access Point URL'
});

Networking.attributes.add('publicKey', {
    type: 'string',
    title: 'Public Key'
});

Networking.prototype.initialize = function() {
    this.app.networking = this;
    this.joined = false;

    this.client = new window.MassiveRealmClient.Client({
        debug: true,

        url: this.accessPointUrl,
        publicKey: this.publicKey,

        autoReconnect: true,
        autoReconnectMaxAttempts: 3,
        autoReconnectTimeout: 3000,

        // Room configuration, exported from Room > Export in the Console
        roomConfig: {
            game: {"serverCommands":{"UpdatePosition":{"id":10,"params":[{"name":"commandId","type":"uint8"},{"name":"x","type":"float64"},{"name":"z","type":"float64"}]}},"clientCommands":{"DeletePlayer":{"id":10,"params":[{"name":"commandId","type":"uint8"},{"name":"id","type":"string8"}]},"UpdatePlayer":{"id":11,"params":[{"name":"commandId","type":"uint8"},{"name":"player","type":"model:Player","array_of":"model:Player"}]}},"models":{"Player":{"params":[{"name":"id","type":"string8"},{"name":"x","type":"float64"},{"name":"z","type":"float64"}]}}}
        },

        onConnect: () => {
            console.log('Connected');

            this.app.fire('GameRoom:clearRoom');

            this.client.joinRoom({
                // Room Alias as defined in the Console
                alias: 'game',

                // Use room id to join a specific room
                id: 'room-1'
            });
        },

        onReconnectTry: (retry) => {
            console.log('Trying to reconnect', retry);
        },

        onDisconnect: (error) => {
            this.joined = false;
            console.log('Disconnected', error);

            this.app.fire('GameRoom:clearRoom');
        },

        onJoinRoom: (roomAlias, roomId, isForwarded) => {
            console.log('Joined to room', roomId);
            this.joined = true;

            // To notify other players that I have joined
            this.app.fire('GameRoom:joinRoom');
        },

        onError: (error) => {
            console.log('Connection error', error);
        },

        onCommand: (command, data) => {
            console.log('Command received', command, data);

            // Add a new player to the scene or move if existing
            if (command == 'UpdatePlayer') {
                this.app.fire(
                    'GameRoom:playerUpdate',
                    data.player.id,
                    data.player.x,
                    data.player.z
                );
            }
            // Remove player from the scene
            else if (command == 'DeletePlayer') {
                this.app.fire('GameRoom:playerDelete', data.id);
            }
        },
    });

    window.addEventListener('beforeunload', () => {
        this.client.disconnect(true);
    });

    this.client.connect(true);
};

Networking.prototype.UpdatePosition = function(x, z) {
    if (!this.joined) return;

    this.client.emit('UpdatePosition', {x, z});
};

Project Settings

PlayCanvas - Networking Settings

Optimization Tip

Storing room settings on the client side may significantly reduce network traffic. This way, the client will not need to request the room settings each time it joins a room.

Navigate to the Rooms section and select the room you want to optimize. Then click on Export on the left side and copy the code.

Optimization Code JSON

Paste that JSON into the client-side code, and you're done!

Optimization Paste JSON

More Performance Tips.