Using Excalibur.js with MassiveRealm
Excalibur.js is a friendly TypeScript 2D game engine for the web.
You can use MassiveRealm with Excalibur.js 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
room
.
MassiveRealm Server Setup
In this demo, player synchronization occurs every 100 ms, batching updates for all players who have changed their position during that interval.
Try the demo:
https://demo-excalibur-js.mrfiles.net/
Client-side source code:
https://github.com/MassiveRealm/demo-excalibur
Server-side:
https://console.massiverealm.com/account/project/e50f-8a0e-74c9
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 - Int16
y - Int16
Step 2: Create Server Command
Navigate to the Communication > Server
section in your project's logic.
Create a new command called Update
with the following input parameters:
x - Int16
y - Int16
This command will be called by the client to update the player's position.
Add the following code to update the player's position in the players collection.
Later we will create a timer to broadcast the players' positions to all clients every 100 ms.
if (!$room.players) $room.players = {};
$room.players[$session.id] = {
id: $session.id,
x: $params.x,
y: $params.y
};
Step 3: Create Client Commands
Navigate to the Communication > Client
section in your project's logic. Here we will create 3 commands:
Command 1: MyInfo
Input Parameters:
id - String
Command 2: UpdatePlayers
Input Parameters:
players - Array Of, Item Type: "Player"
Command 3: DeletePlayer
Input Parameters:
id - String
Step 4: Hooks
Navigate to the Communication > Hooks
section in your project's logic. Here we will create 2 hooks:
Hook 1: OnRoomJoin
Notify the client of its own player ID by emitting the MyInfo
command.
$session.emit('MyInfo', {
id: $session.id
});
Hook 2: OnRoomLeave
Remove the player from the players collection when they leave the room and broadcast the DeletePlayer
command to all other players.
if ($room.players && $room.players[$session.id]) {
delete $room.players[$session.id];
}
$room.broadcast('DeletePlayer', {
id: $session.id
});
Step 5: Create Timer
Navigate to the Timers > Instance
section in your project's logic.
Create a new timer called UpdatePlayersTimer
, set the interval to 100 ms.
Create batches of 30 players per message to avoid network congestion.
if (!$room.players) return;
let players = Object.values($room.players);
if (!players.length) return;
$room.players = {};
for (let i = 0; i < players.length; i += 30) {
const chunk = players.slice(i, i + 30);
$room.broadcast('UpdatePlayers', {
players: chunk
});
}
Excalibur.js Client Setup
Step 1: Add MassiveRealm Client
npm i massiverealm-client
Step 2: Add Network Class
Define your commands in the onCommand
method.
this.client = new MassiveRealmClient({
...
onCommand: (command, data) => {
console.log('Command received', command, data);
// Set current player ID
if (command === 'MyInfo') {
this.playerId = data.id;
}
// Remove player from the scene
else if (command === 'DeletePlayer') {
this.level.events.emit('playerDelete', data.id);
}
// Update all players' positions
else if (command === 'UpdatePlayers') {
for (let i = 0; i < data.players.length; i++) {
// Skip the current player
if (data.players[i].id === this.playerId) continue;
this.level.events.emit('playerMove', {
id: data.players[i].id,
x: data.players[i].x,
y: data.players[i].y
});
}
}
},
...
});
Check out more details in the source code: https://github.com/MassiveRealm/demo-excalibur/blob/main/src/network.ts
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.
Paste that JSON into the client-side code, and you're done!
More Performance Tips.