9.6 KiB
Cupid Matchmaker API Documentation
Overview
Cupid Matchmaker is a matchmaking daemon server designed for Unity game matchmaking. It manages player queues, creates game rooms, and spawns game instances when enough players are available.
Version: v1.0
Base URL: http://localhost:2612 (configurable via settings.json)
Authentication
All endpoints require authentication via a password query parameter. The password is configured in settings.json.
Note: All requests must include ?password=<your_password> in the query string.
Endpoints
1. Get Server Settings
Retrieve the current server configuration settings.
Endpoint: GET /settings
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
password |
string | Yes | Server password for authentication |
Response (200 OK):
{
"minimum_players": 2,
"maximum_players": 2,
"waiting_time": 60000,
"port_range_min": 26000,
"port_range_max": 27000,
"games": [
{
"id": "soccar",
"exe": "/home/react/CupidServer/games/soccar/soccar.x86_64"
}
]
}
Response Fields:
minimum_players(number): Minimum number of players required to start a gamemaximum_players(number): Maximum number of players allowed in a roomwaiting_time(number): Room expiration time in millisecondsport_range_min(number): Minimum port number for game instancesport_range_max(number): Maximum port number for game instancesgames(array): List of available game configurationsid(string): Game identifierexe(string): Path to game executable
Error Responses:
403 Unauthorized: Invalid password
Example Request:
curl "http://localhost:2612/settings?password=HelloWorld"
2. Matchmaking (Join Queue / Get Room)
Main endpoint for matchmaking. Players use this endpoint to join the queue or retrieve their current room information.
Endpoint: GET /
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
password |
string | Yes | Server password for authentication |
username |
string | Yes | Player's username (minimum 2 characters) |
game_name |
string | Yes | Name/identifier of the game to matchmake for |
Response Scenarios:
Scenario 1: Player Already in a Room (200 OK)
Returns the room object if the player is already assigned to a room.
{
"Players": [
{
"Name": "player1",
"LastSeen": 1234567890
},
{
"Name": "player2",
"LastSeen": 1234567891
}
],
"GameName": "soccar",
"Port": 26150,
"InitTime": 1234567800
}
Scenario 2: Room Created (200 OK)
Returns a new room when enough players are in the queue and a room is created.
{
"Players": [
{
"Name": "player1",
"LastSeen": 1234567890
}
],
"GameName": "soccar",
"Port": 26150,
"InitTime": 1234567890
}
Scenario 3: Joined Existing Room (200 OK)
Returns the room when a player joins an existing room that has available slots.
{
"Players": [
{
"Name": "player1",
"LastSeen": 1234567890
},
{
"Name": "player2",
"LastSeen": 1234567891
}
],
"GameName": "soccar",
"Port": 26150,
"InitTime": 1234567800
}
Scenario 4: Added to Queue (200 OK)
Returns "0" when the player is added to the queue or is already in the queue waiting for other players.
"0"
Response Fields:
Players(array): List of players in the roomName(string): Player's usernameLastSeen(number): Unix timestamp of last activity
GameName(string): Name of the gamePort(number): Port number assigned to the game instanceInitTime(number): Unix timestamp when the room was created
Error Responses:
403 Unauthorized: Invalid passwordBad credentials: Username is less than 2 characters
Behavior Notes:
- Players must poll this endpoint regularly (within 2 seconds) to maintain their queue position
- Rooms expire after
waiting_timemilliseconds - Players are removed from the queue if inactive for more than 2 seconds
- When enough players are in the queue (≥
minimum_players), a new room is created and a game instance is spawned - Players can join existing rooms if they have available slots and match the
game_name
Example Request:
curl "http://localhost:2612/?password=HelloWorld&username=player1&game_name=soccar"
3. Cancel Queue Entry
Remove a player from the matchmaking queue.
Endpoint: GET /cancel
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
password |
string | Yes | Server password for authentication |
username |
string | Yes | Player's username to remove from queue |
Response (200 OK):
"1": Successfully removed from queue
Error Responses:
403 Unauthorized: Invalid passwordBad credentials: Username is less than 2 characters"Couldn't find user <username> in the queue": User not found in queue
Example Request:
curl "http://localhost:2612/cancel?password=HelloWorld&username=player1"
Data Models
Player
{
Name: string; // Player's username
LastSeen: number; // Unix timestamp of last activity
}
Room
{
Players: Player[]; // Array of players in the room
GameName: string; // Name/identifier of the game
Port: number; // Port number for the game instance
InitTime: number; // Unix timestamp when room was created
}
QueueEntry
{
Name: string; // Player's username
LastSeen: number; // Unix timestamp of last activity
}
Server Configuration
The server is configured via settings.json:
{
"port": 2612,
"password": "HelloWorld",
"minimum_players": 2,
"maximum_players": 2,
"waiting_time": 60000,
"port_range_min": 26000,
"port_range_max": 27000,
"game_exe": [
{
"name": "soccar",
"exe": "/home/react/CupidServer/games/soccar/soccar.x86_64"
}
],
"log_level": 1
}
Configuration Fields:
port(number): Server listening portpassword(string): Authentication password for API accessminimum_players(number): Minimum players required to start a gamemaximum_players(number): Maximum players allowed per roomwaiting_time(number): Room expiration time in millisecondsport_range_min(number): Minimum port for game instancesport_range_max(number): Maximum port for game instancesgame_exe(array): Game executable configurationsname(string): Game identifierexe(string): Path to game executable
log_level(number): Logging verbosity (0 = minimal, 1 = debug, 2 = verbose)
Matchmaking Flow
-
Player Joins Queue:
- Player calls
GET /withusernameandgame_name - If not enough players in queue, player receives
"0"and is added to queue
- Player calls
-
Room Creation:
- When queue reaches
minimum_players, a new room is created - A random port is selected from the configured range
- A game instance is spawned with the selected port
- First player receives the room object
- When queue reaches
-
Room Joining:
- Subsequent players calling
GET /can join existing rooms with available slots - Players receive the room object with updated player list
- Subsequent players calling
-
Room Expiration:
- Rooms expire after
waiting_timemilliseconds - Expired rooms are automatically cleaned up
- Rooms expire after
-
Queue Maintenance:
- Players must poll
GET /at least every 2 seconds to stay in queue - Inactive players are automatically removed from queue
- Players must poll
Error Handling
All endpoints return appropriate HTTP status codes:
200 OK: Successful request403 Unauthorized: Authentication failure- Error messages are returned as plain text in the response body
Best Practices
- Polling Frequency: Poll the matchmaking endpoint (
GET /) every 1-2 seconds to maintain queue position - Error Handling: Always check for
403 Unauthorizedresponses and handle authentication errors - Username Validation: Ensure usernames are at least 2 characters long
- Room Management: Once a room is received, connect to the game instance on the provided port
- Queue Cancellation: Use
/cancelendpoint when a player wants to leave the queue
Example Integration
JavaScript/TypeScript Example
const BASE_URL = 'http://localhost:2612';
const PASSWORD = 'HelloWorld';
const USERNAME = 'player1';
const GAME_NAME = 'soccar';
// Join matchmaking queue
async function joinMatchmaking() {
const url = `${BASE_URL}/?password=${PASSWORD}&username=${USERNAME}&game_name=${GAME_NAME}`;
const response = await fetch(url);
const data = await response.text();
if (data === '0') {
console.log('Added to queue, waiting for players...');
// Poll every 1.5 seconds
setTimeout(joinMatchmaking, 1500);
} else {
const room = JSON.parse(data);
console.log('Room found!', room);
console.log(`Connect to game on port ${room.Port}`);
}
}
// Cancel queue
async function cancelQueue() {
const url = `${BASE_URL}/cancel?password=${PASSWORD}&username=${USERNAME}`;
const response = await fetch(url);
const result = await response.text();
console.log('Cancel result:', result);
}
Notes
- The server automatically spawns game instances when rooms are created
- Game instances are launched with the
-portargument - Rooms are automatically cleaned up when expired or empty
- The queue has a grace period of 2 seconds for player inactivity
- All timestamps are Unix timestamps in milliseconds