This is a simple matchmaking server that can be used for any game.
Developing an online multiplayer game is hard. Not only do you need to develop your game, you also need to think about networking, create a communication protocol and develop server software. "Matchmaking" does all the multiplayer-related aspects for you, all you need to do is to create your game. On the other hand, "Matchmaking" doesn't do anything else: It's not a game engine and gives you complete freedom in how you create your game.
- Can be used for any game (*)
- Easy configuration through a web interface, command line parameters or configuration files [WIP]
- JSON api (over HTTP)
- Create rooms of any size
- Global white-/blacklist support
- Per-room white-/blacklist support
- Games can be resumed even after a client looses the connection
- Scalable: Can be launched with a single command on one single node or distributed over a large network of nodes [WIP]
(*): You can program your game in any programming language. Furthermore, you can use any game engine that you want to create your game or write your game from scratch. The only thing that your game needs to have is the ability to communicate via HTTP and work with JSON.
This project is far from being finished, but it is already in a usable state. You can therefore go ahead and download the server software to start experimenting with it, but keep the following in mind:
- You are using a snapshot build. This means that things can change from one moment to another without prior notice.
- The server can currently only run on one single node as I am still working on database integrations.
- For the same reason, data is currently not persisted across server restarts.
- You currently have to stick with the default configuration as I am still working on the configuration utilities.
- You will have to write your own client as I didn't have the time yet to create one. (You are always welcome to contribute your client through a pull request)
Development is still in progress and precompiled artifacts are not yet available (but will be available soon, though). You therefore need to build the server yourself as described below in the section "Building from source".
- JRE 8 or above (though only tested with JRE 8)
"Matchmaking" comes with a standalone launcher which uses Tomcat 8 as its basis. The standalone launcher can simply be launched with tis command:
java -jar matchmaking.standalone-server-launcher-1.0-SNAPSHOT-jar-with-dependencies.jar --PORT 8080
Replace 8080
with the port you want the server to listen on.
You can use any Java Servlet container like Tomcat or Jetty to run the war file or deploy it to PaaS-providers like Heroku.
To do so, please follow your container's instructions on how to deploy a war
file and deploy the file called matchmaking.server-1.0-SNAPSHOT.war
.
There will be a docker image which you can use to run the server, but that is a huge work in progress.
Open your browser and navigate to the URL of your server (http://localhost:8080
if you're running the server on your machine).
You should be greeted by a welcome message.
Building the server from source is actually quite simple and only requires the following to be installed:
- Java JDK 1.8
- Maven 3 or higher
To build the software from source, do the following
- Clone or download the repository (Use the big green button in the upper right corner). If you downloaded the repository, unzip it, before continuing.
- Open your command line and use
cd
to navigate into the project directory - Type
mvn package
, hit enter and watch the magic happen (Usemvn package -DskipTests=true
to skip the unit tests)
Once the build has finished, you will find the compiled artifacts at the following places:
- The server war:
server/target/matchmaking.server-1.0-SNAPSHOT.war
- The standalone server launcher:
standaloneserverlauncher/target/matchmaking.standalone-server-launcher-1.0-SNAPSHOT-jar-with-dependencies.jar
- Clients connect themselves to the server and tell the server that they wish to connect to a room.
- If the client is the first to connect, a new room will be created, and the client will have to wait for the room to become full.
- Clients who connect afterwards will be assigned to the same room until the room is full, and a game can begin.
- Once the game has started, the server acts as a relay station. Clients send updates to the server, and the server distributes the current state of the game to all clients. This technique circumvents the need for peer-to-peer connections between the players.
- One client will become the so-called host of the game. This client verifies that all other clients play within the rules and tells the server if there is something off.
- If a client looses its connection to the server but manages to reconnect eventually, the server will recognize the client, and the game can resume.
Good news! We will be providing a client for you (once we finished development, obviously ;) ), so you can focus on your game. Again, it's not yet finished, so hang tight :)
If your language is not a JVM-language, you will have to write your own client and implement the communication protocol yourself. Consider submitting your implementation through a pull-request if you wish to share it with the public.
All communication happens over HTTP through JSON-formatted requests. All requests must be sent to
http://host:port/matchmaking
(or https://host:port/matchmaking
if you use https
)
The server doesn't care too much about what headers you send, just two rules that you should follow:
- Set
Content-Length
to the correct value or omit it if you don't know the length of the request - Set
Content-Type
toapplication/json
The actual request is sent in the HTTP request body and is formatted as JSON. Requests always follow this pattern:
{
"className": "<requestType>",
"additionalParameterName": "parameterValue"
}
The className
property specifies the type of the request.
The className
of a request always starts with com.github.vatbub.matchmaking.common.requests
The responses given by the server follow the same pattern as requests, except that the className
starts with com.github.vatbub.matchmaking.common.responses
.
In addition, the server uses HTTP status codes to indicate the nature of the response.
During the communication, the client will have to send multiple requests to the server. Unfortunately, HTTP does not provide a reliable way for the server to recognize clients.
Hence, the very first request that a client needs to send is a GetConnectionIdRequest
which always looks like this:
{
"className": "com.github.vatbub.matchmaking.common.requests.GetConnectionIdRequest"
}
The server will then assign a connectionId
and a password
to the client and return those credentials using a GetConnectionIdResponse
which will look like so:
{
"password": "3450e711",
"httpStatusCode": 200,
"connectionId": "79f96ee2",
"className": "com.github.vatbub.matchmaking.common.responses.GetConnectionIdResponse"
}
The client is expected to remember the connectionId
and the password
for later communication.
Players who are playing together are grouped in rooms. There can be multiple rooms at the same time and each room is completely independent of other rooms. That means:
- Different rooms can be in different stages in the game
- Different rooms can have different game rules
Additional things to keep in mind:
- One Player (i.e. one
connectionId
) can only be in one room at a time
To create or join a room, the client needs to send a JoinOrCreateRoomRequest
which looks like so:
{
"operation": "JoinOrCreateRoom",
"userName": "vatbub",
"userList": [
"heykey",
"mo-mar"
],
"userListMode": "Whitelist",
"minRoomSize": 1,
"maxRoomSize": 2,
"connectionId": "79f96ee2",
"password": "3450e711",
"className": "com.github.vatbub.matchmaking.common.requests.JoinOrCreateRoomRequest"
}
Parameters:
parameter | possible values | explanation |
---|---|---|
operation |
JoinOrCreateRoom , JoinRoom CreateRoom |
Specifies what operation shall be done. JoinOrCreateRoom will cause the player to join a room if an applicable room is found or create a new room if no matching room was found. JoinRoom will do the same except that nothing will happen if no applicable room can be found. CreateRoom will force the creation of a new room. |
userName |
Any string value | The human-readable user name that was picked by the user. Similar to the XBox Gamertag or PSN-ID |
userList |
Array of strings | White- or blacklist of usernames |
userListMode |
Whitelist , Blacklist or Ignore |
Specifies how userList shall be treated. Whitelist : Only users mentioned in userList will be allowed to join the room. Blacklist : Users mentioned in userList will not be allowed to join the room. Ignore (default): userList will have no effect. |
minRoomSize |
Any integer value above or equal to 0 | The minimum amount of players required to start a game. |
maxRoomSize |
Any integer value above or equal to 0. Should be above or equal to minRoomSize |
The maximum amount of players allowed in a room. |
connectionId |
The sending client's connectionId as assigned by the server in the GetConnectionIdResponse |
|
password |
The sending client's password as assigned by the server in the GetConnectionIdResponse |
The JoinOrCreateRoomResponse
returned by the server will look like so:
{
"result": "RoomCreated",
"roomId": "73065963",
"httpStatusCode": 200,
"connectionId": "79f96ee2",
"className": "com.github.vatbub.matchmaking.common.responses.JoinOrCreateRoomResponse"
}
Parameters:
parameter | possible values | explanation |
---|---|---|
result |
RoomCreated , RoomJoined Nothing |
The operation that was performed on the server as a result of the request. |
roomId |
String | The id of the room that was created or that the player joined. This id can later be used to retrieve information about the room or to modify the room's contents. |
Once a room was created or joined, the client can request additional information about the room it was assigned to using a GetRoomDataRequest
:
{
"roomId": "73065963",
"connectionId": "79f96ee2",
"password": "3450e711",
"className": "com.github.vatbub.matchmaking.common.requests.GetRoomDataRequest"
}
Parameters:
parameter | possible values | explanation |
---|---|---|
roomId |
String | The roomId as specified by the JoinOrCreateRoomResponse |
connectionId |
The sending client's connectionId as assigned by the server in the GetConnectionIdResponse |
|
password |
The sending client's password as assigned by the server in the GetConnectionIdResponse |
The 'GetRoomDataResponse` returned by the server will look like so:
{
"room": {
"connectedUsers": [],
"gameState": {
"contents": {}
},
"gameStarted": false,
"dataToBeSentToTheHost": [],
"id": "73065963",
"hostUserConnectionId": "79f96ee2",
"configuredUserNameList": [
"heykey",
"mo-mar"
],
"configuredUserNameListMode": "Whitelist",
"minRoomSize": 1,
"maxRoomSize": 2
},
"httpStatusCode": 200,
"connectionId": "79f96ee2",
"className": "com.github.vatbub.matchmaking.common.responses.GetRoomDataResponse"
}
Parameters:
parameter | possible values | explanation |
---|---|---|
room |
Room-object | Object which contains information about the requested room. (See below for an explanation of Room-objects) |