TypeScript Client

Getting Started

The MatchmakeClient library provides an easy way to connect to the Matchmake.io service in both browser and Node.js environments.

Installation

# Install the client library
npm install matchmake-client
# For Node.js environments, also install WebSocket support
npm install ws

Basic Usage

import { MatchmakeClient } from 'matchmake-client';
// Create a client instance
const client = new MatchmakeClient('wss://api.matchmake.io/socket', {
apiToken: 'your-api-token', // Optional: defaults to a demo token
debug: true // Optional: enables logging
});
// Set up event listeners
client.on('connected', (configs) => {
console.log('Connected with configurations:', configs);
});
client.on('lobbyUpdate', (lobby) => {
console.log('Lobby updated:', lobby);
});

Authentication

Connect to the matchmaking service and authenticate a player:

Connecting

// Connect to the matchmaking service
async function connect() {
try {
const configs = await client.connect({
playerSlug: 'player123', // Player identifier
ipAddress: '127.0.0.1' // Player's IP address
});
console.log('Available matchmaking configurations:', configs);
// Connection successful, now you can find and join lobbies
} catch (error) {
console.error('Connection failed:', error.message);
}
}

The connect method returns a promise that resolves to an array of available matchmaking configurations.

Event Handling

The client emits various events you can listen for:

// Basic connection events
client.on('connected', (configs) => {
console.log('Connected to matchmaking service');
});
client.on('disconnected', () => {
console.log('Disconnected from matchmaking service');
});
client.on('error', (error) => {
console.error('An error occurred:', error.message);
});
client.on('socketError', (error) => {
console.error('Socket error:', error.message);
});
client.on('socketClosed', () => {
console.log('WebSocket connection closed');
});

Lobby Operations

Find, join, and interact with lobbies:

Finding a Lobby

// Find a lobby for a specific configuration
async function findLobby(configId) {
try {
const lobby = await client.findLobby(configId);
console.log('Found lobby:', lobby);
return lobby;
} catch (error) {
console.error('Failed to find lobby:', error.message);
}
}

Joining a Lobby

// Join a specific lobby
async function joinLobby(lobby) {
try {
const joinedLobby = await client.joinLobby(lobby);
console.log('Joined lobby:', joinedLobby);
return joinedLobby;
} catch (error) {
console.error('Failed to join lobby:', error.message);
}
}
// Or use the convenience method to find and join in one step
async function findAndJoinLobby(configId) {
try {
const lobby = await client.findAndJoinLobby(configId);
console.log('Found and joined lobby:', lobby);
return lobby;
} catch (error) {
console.error('Failed to find and join lobby:', error.message);
}
}

Setting Host Information

// Set host information for the current lobby
async function setHostInfo() {
try {
await client.setHostInfo({
type: 'p2p', // 'p2p' or 'dedicated'
address: '192.168.1.100', // Host address
port: 7777 // Host port
});
console.log('Host information set successfully');
} catch (error) {
console.error('Failed to set host information:', error.message);
}
}

Leaving a Lobby

// Leave the current lobby
async function leaveLobby() {
try {
await client.leaveLobby();
console.log('Left lobby successfully');
} catch (error) {
console.error('Failed to leave lobby:', error.message);
}
}
// Disconnect from the matchmaking service completely
function disconnect() {
client.disconnect();
console.log('Disconnected from matchmaking service');
}

Lobby Events

Listen for lobby-specific events:

// Lobby events
client.on('lobbyFound', (lobby) => {
console.log('Lobby found:', lobby);
});
client.on('lobbyJoined', (lobby) => {
console.log('Joined lobby:', lobby);
});
client.on('lobbyUpdate', (lobby) => {
console.log('Lobby updated:', lobby);
});
client.on('lobbyLeft', (lobbyId) => {
console.log('Left lobby:', lobbyId);
});
client.on('playerJoined', (player, lobby) => {
console.log('Player joined:', player.slug);
});
client.on('playerLeft', (player, lobby) => {
console.log('Player left:', player.slug);
});
client.on('statusChanged', (status, lobby) => {
console.log('Lobby status changed to:', status);
});
client.on('hostChanged', (hostInfo, lobby) => {
console.log('Host information changed:', hostInfo);
});
client.on('hostInfoSet', (hostInfo) => {
console.log('Successfully set host info:', hostInfo);
});

Auto Matching

Use auto-matching to let the system find opponents:

Auto-Match Flow

// Using auto-matching to find players
async function startAutoMatch(configId) {
try {
// Connect to the matchmaking service
await client.connect({
playerSlug: 'player123',
ipAddress: '127.0.0.1'
});
// Find and join a lobby with auto-matching
// (Make sure the configuration has lobby_type: 'auto_match')
const lobby = await client.findAndJoinLobby(configId);
console.log('Joined auto-match lobby:', lobby);
// Listen for lobby updates
client.on('statusChanged', (status, updatedLobby) => {
if (status === 'full' || status === 'started') {
console.log('Match is ready to start!');
console.log('Players:', updatedLobby.players);
if (updatedLobby.host_type && updatedLobby.host_address) {
console.log('Host info:', {
type: updatedLobby.host_type,
address: updatedLobby.host_address,
port: updatedLobby.host_port
});
}
}
});
// Listen for player joins
client.on('playerJoined', (player, updatedLobby) => {
console.log('New player joined:', player.slug);
console.log('Current player count:', updatedLobby.players.length);
});
} catch (error) {
console.error('Auto-match failed:', error.message);
}
}

For auto-matching, use a configuration that has lobby_type: 'auto_match'.

Error Handling

The client provides specific error classes to help with error handling:

Error Types

import {
MatchmakeError, // Base error class
ConnectionError, // WebSocket or connection issues
LobbyError // Lobby-related errors
} from 'matchmake-client';
// Example error handling
try {
await client.findAndJoinLobby(configId);
} catch (error) {
if (error instanceof ConnectionError) {
console.error('Connection issue:', error.message);
// Handle connection problems
} else if (error instanceof LobbyError) {
console.error('Lobby issue:', error.message);
// Handle lobby-specific problems
} else {
console.error('Unexpected error:', error.message);
// Handle other errors
}
}

Complete Example

Putting It All Together

import { MatchmakeClient, ConnectionError, LobbyError } from 'matchmake-client';
async function startGame() {
// Create client
const client = new MatchmakeClient('wss://api.matchmake.io/socket', {
apiToken: 'your-api-token',
debug: true
});
// Set up event listeners
client.on('connected', (configs) => {
console.log('Connected with configs:', configs);
});
client.on('lobbyJoined', (lobby) => {
console.log('Successfully joined lobby:', lobby.id);
});
client.on('playerJoined', (player) => {
console.log('Player joined:', player.slug);
});
client.on('statusChanged', (status, lobby) => {
if (status === 'started') {
console.log('Game is starting!');
// Connect to the game host
connectToGame(lobby.host_address, lobby.host_port);
}
});
try {
// Connect to matchmaking service
await client.connect({
playerSlug: 'player123',
ipAddress: '127.0.0.1'
});
// Find and join a lobby
const lobby = await client.findAndJoinLobby(1);
console.log('Joined lobby:', lobby);
// If you're hosting, set host info
if (isHosting) {
await client.setHostInfo({
type: 'p2p',
address: getMyIpAddress(),
port: 7777
});
}
} catch (error) {
if (error instanceof ConnectionError) {
console.error('Connection failed:', error.message);
} else if (error instanceof LobbyError) {
console.error('Lobby error:', error.message);
} else {
console.error('Unexpected error:', error.message);
}
}
}
// Start the matchmaking process
startGame();
// Cleanup when done
function cleanup() {
client.leaveLobby()
.then(() => client.disconnect())
.catch(error => console.error('Cleanup error:', error));
}