The Infinity Game Table ("IGT" for short, which also refers to the Infinity Game Board system) server supports multiplayer. By integrating our multiplayer API you can easily leverage the user's friends list and our IGT dashboard's game invitation system, and add multiplayer support to your game.
This project is a basic sample project demonstrating how to establish multiplayer connection using our IGT multiplayer API. Follow the instructions in this repo to learn how to work with the IGT's multiplayer API.
- You need an Infinity Game Table, either 24" or 32", or an Infinity Game Board
- The package (bundle ID) of the game your are developing on, needs to be listed on the IGT store. Contact us to get set up.
- Clone this project
There are only two classes you need to study. MainActivity.java and MultiplayManager.java.
The multiplayer API uses web socket to communicate. In our sample project, the MainActivity is the listener.
MultiplayManager.getInstance().setMultiplayCallbackListener(this);
Here are the interface functions, it's self-explainatory:
/**
* Callback when a web socket connection is initiated.
*/
void multiplayOnConnect();
/**
* Callback when the web socket connection is opened
*/
void multiplayOnOpen();
/**
* Callback on received a message
* @param message
*/
void multiplayOnMessage(String message);
/**
* Callback on Error
* @param e
* @param error
*/
void multiplayOnError(Exception e, String error);
/**
* Callback when web socket connection closed
*/
void multiplayOnClose();
A game can be launched either by user manually clicking on the game icon on the IGT dashboard, or launched automatically when user accepts a multiplayer invitation. You should always check for pending multiplayer invitation when you first launch your game. In our sample project, we call this function in MainActivity's onCreate:
MultiplayManager.getInstance().checkInvitationAndConnect(getIntent());
This will check for pending multiplayer game invitation and try to establish a web socket connection.
If user wants to be host and invite friends to join his game, simply call:
MultiplayManager.getInstance().sendInvitation(this, packageName, maxPlayer);
packageName needs to exist on our IGT dashboad. Contact us to create a beta testing app on our dashboard.
Calling this function will trigger the game invitation intent and the dashboard will take over from there for user to send invitation to anyone on his/her friends list.
For host:
Once user is done sending out invitation and back to your game, you should receive the web socket URL from onActivityResult, resultCode = -1. Feed the web socket URL back to MultiplayerManager:
channel = data.getStringExtra("channel");
setResult(RESULT_OK, data);
this.runOnUiThread(new Runnable() {
@Override
public void run() {
MultiplayManager.getInstance().connectWsChannel(channel);
}
});
For client:
Follow instructions on step 2.
The web socket system was developed to echo whatever you send to every user connected to the channel. We recommend you send JSON messages, however it’s totally up to you, however each message terminated with the newline is sent as a single message to all other users.
It is also recommended that you enable the PING/PONG protocol on your websocket channel from your side to help maintain channel stability. The server will also have it enabled.
The Websocket protocol implements so called PING/PONG messages to keep Websockets alive, even behind proxies, firewalls and load-balancers. The server sends a PING message to the client through the Websocket, which then replies with PONG. If the client does not reply, the server closes the connection.
When sending a message, a success response would look like:
Responses for connections/commands
{
“Status”:”OK” // or ErrorCode
“Message”:”” // verbose message of error
“Payload”:”” // optional payload
}
The message is then relayed to all users on the channel (including yourself) in this format:
{
“ID”: int // Unique ID for each message
“Timestamp”: int // Time since Jan 1, 1970,
“FromHandle”:”” // from which user (blank for admin message)
“Payload: string // message payload -- see below
}
ID will be an ever increasing (however not sequential) integer.
Timestamp is the time the message was sent FromHandle will be a string representation of the sender’s Handle
Payload is a string representation of the payload you wrote to the channel. It will not be JSON until you decode it.
On both game and admin channels you can replay the messages starting at the last one you received, or 0 for all.
CMD:REPLAY:0
If the last message you received was 9 and you disconnected, you can get ID > 9 by passing in
CMD:REPLAY:9
Anything not in the format /^CMD:/ will just be relayed to the entire game channel wrapped in the Outbound Payload Wrapper below in the Payload field.
A muted message is a message that will be relayed realtime to all connected parties, however won’t be saved for future REPLAY command. These can be used for things like connect messages, PING’s etc.
CMD:SENDMUTED:some payload here
Example:
CMD:SENDMUTED:{“pingFrom”: “Bill”}
Timeout values for web sockets:
- 10 minutes for an idle connection
- 2 hours per connection (must reconnect after being disconnected)
If disconnected, the client should reconnect and utilize the REPLAY cmd to see if they’ve missed any messages.
Max Message Size: 30kb
An http status code of 403 means that something is wrong with your key/credentials
Rate Considerations: this is not a realtime system meant for fast message broadcasting. Do not try and send more than a message per second.