websocket-game-lobby v4.1.1
websocket-game-lobby
🔧 Simple API for building games using WebSockets.
Install
$ npm install websocket-game-lobby
Quick Start
The following example starts a WebSocket server and a single page HTTP server using http-single-serve.
Without any additional code, this server can be connected to, and then a game can be created
, joined
, started
, left
, and ended
. This can be done using either the websocket-game-lobby-client package or the React hook websocket-game-lobby-client-hooks package.
const http = require('http-single-serve');
const { WebSocketGameLobbyServer } = require('websocket-game-lobby');
const gameLobby = new WebSocketGameLobbyServer({
server: http({
port: 5000
})
});
Custom events can be added by using event listeners on either the server or the datastore.
For example, a custom event can be added to the server to set a property when a game is created. In the following example, a custom property with the key of color
will be added with a value of purple
when a game is created.
const http = require('http-single-serve');
const { WebSocketGameLobbyServer } = require('websocket-game-lobby');
const gameLobby = new WebSocketGameLobbyServer({
server: http({
port: 5000
})
});
gameLobby.addEventListener(
'create',
async ({ gameId, playerId }, datastore) => {
await datastore.editGame(gameId, async game => {
game.custom.color = 'purple';
return game;
});
}
);
You can also create custom events, in addition to the built-in events, that can be called in the same way from the client.
const http = require('http-single-serve');
const { WebSocketGameLobbyServer } = require('websocket-game-lobby');
const gameLobby = new WebSocketGameLobbyServer({
server: http({
port: 5000
})
});
gameLobby.addEventListener(
'card-played',
async ({ gameId, playerId, turnId, playedCard }, datastore) => {
await datastore.editTurn(gameId, turnId, async turn => {
if (!turn.custom.playedCards) {
turn.custom.playedCards = [];
}
turn.custom.playedCards.push({
playerId,
playedCard
});
return turn;
});
}
);
You can even set custom events directly on the datastore. In this example, we are manually creating a datastore and attaching an event. When a game is created, a custom property with the key of createdDate
will be added with a value of Date.now()
.
const http = require('http-single-serve');
const {
WebSocketGameLobbyServer,
EphemeralDataStore
} = require('websocket-game-lobby');
const datastore = new EphemeralDataStore();
datastore.addEventListener('createGame', async (game, datastore) => {
game.custom.createdDate = Date.now();
return game;
});
const gameLobby = new WebSocketGameLobbyServer({
server: http({
port: 5000
}),
datastore
});
API
WebSocketGameLobbyServer
Event types for use with the WebSocketGameLobbyServer are as follows:
Name | Description |
---|---|
create | Event fired when a game is created. |
join | Event fired when a game is joined. |
leave | Event fired when a game is left. |
start | Event fired when a game is started. |
end | Event fired when a game is ended. |
Each event uses the same callback signature of ({gameId, playerId, ...rest}, datastore)
. The rest
refers to all other key-value pairs recieved from client, including custom ones.
addEventListener
Add a new event callback method for an existing or new event type.
const createHandler = async ({ gameId, playerId }, datastore) => {};
gameLobby.addEventListener('create', createHandler);
removeEventListener
Remove an existing event callback method. Callback must be a reference to the original added method.
const createHandler = async ({ gameId, playerId }, datastore) => {};
gameLobby.removeEventListener('create', createHandler);
removeAllEventListeners
Remove all existing event callback methods.
gameLobby.removeAllEventListeners();
DataStore
There are two kinds of DataStore objects you can use; the default is EphemeralDataStore
, which stores data in a temporary JavaScript object, and the other is PostgresDataStore
.
EphemeralDataStore
const { EphemeralDataStore } = require('websocket-game-lobby');
const datastore = new EphemeralDataStore();
PostgresDataStore
To connect to your database, add the following into an .env
file in your project and setup the ENV variables on your server.
WARNING: Make sure an add
.env
to your.gitignore
file to prevent committing passwords to your git repository.
PGHOST=localhost
PGPORT=5432
PGUSER=postgres
PGPASSWORD=password
PGDATABASE=travis_ci_test
Then install dotenv and import it into your project. This will parse the variables in your .env
file and expose them to your project for reading via the process.env
object.
require('dotenv').config();
const { PostgresDataStore } = require('websocket-game-lobby');
const datastore = new PostgresDataStore();
Event types
Event types for use with the DataStore are as follows:
Name | Description |
---|---|
createGame | Event fired when a game is created. |
leaveGame | Event fired when a game is left. |
startGame | Event fired when a game is started. |
createPlayer | Event fired when a player is created. |
createSpectator | Event fired when a spectator is created. |
createTurn | Event fired when a turn is created. |
endCurrentTurn | Event fired when a turn is ended. |
Each event uses the same callback signature of (data, datastore)
. The data
refers to the type of object is being modified, as referenced in the event name.
addEventListener
Add a new event callback method for an existing or new event type.
const gameCreatedHandler = async (game, datastore) => {};
datastore.addEventListener('gameCreated', gameCreatedHandler);
removeEventListener
Remove an existing event callback method. Callback must be a reference to the original added method.
const gameCreatedHandler = async (game, datastore) => {};
datastore.removeEventListener('gameCreated', gameCreatedHandler);
removeAllEventListeners
Remove all existing event callback methods.
datastore.removeAllEventListeners();
findGame
Find a game using a UUID.
const game = await datastore.findGame('8ca2ad81-093d-4352-8b96-780899e09d69');
findGameWithCode
Find a game using a game code.
const game = await datastore.findGameWithCode('ABCD');
editGame
Edit game data.
const editedGame = await datastore.editGame(gameId, async game => {
return game;
});
findPlayer
Find player in a game using a UUID.
const player = await datastore.findPlayer(gameId, playerId);
editPlayer
Edit player data.
const editedPlayer = await datastore.editPlayer(
gameId,
playerId,
async player => {
return player;
}
);
findSpectator
Find spectator in a game using a UUID.
const spectator = await datastore.findSpectator(gameId, spectatorId);
editSpectator
Edit spectator data.
const editedSpectator = await datastore.editSpectator(
gameId,
spectatorId,
async spectator => {
return spectator;
}
);
findTurn
Find turn in a game using a UUID.
const turn = await datastore.findTurn(gameId, turnId);
findCurrentTurn
Find the current turn in a game using a UUID.
const turn = await datastore.findCurrentTurn(gameId);
editTurn
Edit turn data.
const editedTurn = await datastore.editTurn(gameId, turnId, async turn => {
return turn;
});
editCurrentTurn
Edit current turn data.
const editedTurn = await datastore.editCurrentTurn(gameId, async turn => {
return turn;
});
endCurrentTurn
Ends current turn and then creates a new turn in a game.
await datastore.endCurrentTurn(gameId);
Packages
Package | Description | Version |
---|---|---|
websocket-game-lobby-client | Simple API for building games using WebSockets. | |
websocket-game-lobby-client-hooks | React hooks for use with websocket-game-lobby | |
websocket-game-lobby-template | Template built with websocket-game-lobby |