Tuesday, October 18, 2016

Easy Network Programming For Games

When you start developing your latest multiplayer game, and get onto the networking aspect, do you wish there was a way to avoid having to re-write the same code over and over again?  All the handling of sockets, multiple network threads, keeping track of clients etc...?  Me too, so that's why I wrote the Generic Multiplayer Connector.

The Generic Multiplayer Connector (GMC) is a library to help turn any single-player game into a multi-player game by allowing clients to easily connect to a shared server and pass data to each other without having to worry about all the usual networking complications. It uses a client/server model, and when a client sends out any data, it is automatically received by all other clients in the same game. Clients also receive notifications of when a game has been won and who the winner was.

GMC is also completely open source and can be downloaded here: https://bitbucket.org/SteveSmith16384/genericmultiplayerconnector 

Why should I use GMC?

That's a very good question. There are lots of other networking libraries out there. However, the real advantage of GMC is that it requires minimal setup, configuration and handling:
  • Running the server is simple a case of running a jar. Because the server is generic, a single server can be used for any number of different games.
  • Once a client is connected, it can send data, and will automatically receive data, from all the other clients playing in the same game. All you need to do is decide when to send data, what data to send, and what to do with the data when it's received.
  • You don't need to worry about handling network connections, multithreading, keeping track of other players etc.. Just send and receive data.
  • There are built-in methods for accessing the current status of the game (waiting for players, started, finished), notification when a player has joined/left, and who the winner of the game was.
  • There is a free publicly-accessible server waiting for you to use.


Example Code

Running the server:-
    // Run this in a command prompt
    java -jar GMCServer.jar 
All the following code is run on the clients.

Connecting to the server:-
    // This will bring up a form for the user to enter an IP address etc..
    ConnectorMain connector = StartGameOptions.ShowOptionsAndConnect(this);

    // Alternatively, if you have your own method of getting the 
    // connection details:
    ConnectorMain connector = new ConnectorMain(this, "", 
        9996, "Steve", "MyGame", 2, 99);
Joining a game:-
Sending data to all other clients:-
    // There are other ways, this sends a key/value pair by TCP.
    connector.sendKeyValueDataByTCP(code, score); 
Receving data
    // 'game' is your class that implements the IGameClient interface.
    game.dataReceivedByTCP(int fromplayerid, int code, int value);
Damn, I've been killed in the game
I've got to the end! Was I the first?
But who has the server confirmed as the winner?
    System.out.println("The winner was " + connector.getWinnersName() + "!");


 Quickstart Guide

These are step-by-step instructions on how to incorporate it into your project:-
  • Run the server GMCServer.jar, or decide to use the public server described below.
  • Add the GMCClient.jar to your project.
  • implement the IGameClient interface in a class in your game.
  • Create instance of ConnectorMain().
  • Call ConnectorMain.connect() to connect to the server
  • Call ConnectorMain.joinGame() to join a game.
  • Wait until all players have connected ("ConnectorMain.getGameStage() == GameStage.IN_PROGRESS") and then start your main game loop.
  • Send data to other clients with any of the ConnectorMain.sendKeyValue..., ConnectorMain.sendString... or ConnectorMain.sendByteArray... methods. All the other clients will receive any data sent.
  • Receive data using any of the IGameClient.dataReceived... interface methods.
  • Call ConnectorMain.sendIAmTheWinner() if your client won the game, or call ConnectorMain,sendOutOfGame() if your client is out of the game.
  • End your game when "ConnectorMain.getGameStage() == GameStage.FINISHED", or if your client has finished (i.e. the player has died), call ConnectorMain.waitForGameToFinish().
  • Once the game has finished, you can get the winner's name with ConnectorMain.GetWinnersName().
  • You can then call ConnectorMain.joinGame() to join/start another game, or ConnectorMain.disconnect() to close all network connections.


Public Server

I run a server at that can be used by anyone.  As stated above, any GMC server can be used for any game or any number of games.  (See the source file Statics.java for the port). Note that this server is not guaranteed to be available 24/7 forever though, and should not be used for anything mission-critical.

No comments: