Java multiplayer game - networking concepts

Bv202 picture Bv202 · Sep 28, 2011 · Viewed 11.6k times · Source

For a school project, we're supposed to create a multiplayer game in Java (it should be client/server) which can be played over the internet (we're programming this at school, so it's not homework). The game is turn-based, but there should be a chat, which ofcourse is real-time. However, none of us has experience with network programming and the more I read about it, the more questions I seem to have.

My first thought was to use the socket API to implement the multiplayer part. The server waits for new data from the clients. However, there are multiple kinds of data to receive, like chat messages, movement, etc. Also, once the connection to the server is made, some initial data (like the Player's name) should be sent. The server should be able to see what kind of message it received, but how? I was thinking of creating a class Message with a string field type. But in my server code, I will get code like this:

if (message.type.equals("message")) {
  // code to execute for chat messages
} else if (message.type.equals("movement")) {
  // code to execute for movement
} else if () {
  // ...
} else {
  // ...
} // Please ignore syntax errors :P

When there are a lot of different kinds of data to send (and there WILL be), this doesn't look like the most efficient way. Also, this would mean both the server and client should have this Message-class/interface (duplicate code).

What about other game stuff? For example, player 1 moves his character to a position which defeats another character. The client of player 1 calculates this defeatment and applies the correct actions. But what should be send to the server? Just the new player position or also the defeatment? With the first option, it means all other clients should do the calculations. Couldn't this cause any trouble? As I have no prior network programming experience, I'm a bit confused on how to do all these things.

I've also read in another thread here on Stackoverflow that RMI might be a better option. Having read some information about this, I understand what RMI is, but I'm still not able to see whether it is a good option for this project or not. Any tips for this?

As you see, I'm a bit confused on how to start with the networking part of this project. I've searched for some game programming books (for Java ofcourse), but none of them are focussed on the networking part. I've also searched for Java networking books, but these seem to be focussed on the technology, not on good code practices.

If anyone knows a good book or has some advice in the right diection, it would be greatly appreciated.

Thanks

Answer

dfb picture dfb · Sep 28, 2011

You're on the right path, but there are few things to clear up.

If you're using sockets, you've figured out that you need to define a protocol - a mutual language for communicating moves and the state of the game. Sockets will let you send any sort of data in pretty much any format you want. It looks like you're thinking about serializing a class Message to send this type, this is one of doing things. If you use RMI (which has its own protocol), you will act as if you were calling Java methods, but in essence you're doing something similar, serializing data and passing it over a socket.

There's nothing implicitly wrong about sharing code between the client and the server - in fact, most services do this in some form. Your client and server could both use a common library to define the message classes being passed around. RMI uses method stubs to determine the interface. Web services of all sorts define how methods are invoked. The general idea is to only expose the interface, not the implementation.

Regarding your code, it might be cleaner to have a different Message subclass for each message type and you could put additional parameters for each message. You could then have a MessageProcessor class like:

class MessageProcessor{
    void process(Move1Message m) {...}
    void process(Move2Message m) {...}
    ....

}

Regarding what to send - the general principle should be that the client is responsible for sending their move to the server, anything else it does is a bonus, because the server needs to verify the legality of the move. The server should always be the determiner of the state of the game to avoid cheating and erroneous client implementations

Unless you're interested in learning how to implement your own protocol or use the Java sockets library, it's going to be easier to use RMI. You could also use SOAP, REST or any other protocol, but I wouldn't bother thinking too hard about which one to use at the moment. I don't have any suggestions beyond the RMI documentation, though I think this book had lots of code examples for networking.