Java multiplayer game - networking concepts
Asked Answered
C

2

9

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

Carnage answered 28/9, 2011 at 17:2 Comment(3)
@CPerkins: We're supposed to work on this project at school, yes. I'm not asking anyone to make my work, just asking advice on how to to implement this.Carnage
@Carnage - "homework" is understood (at least here) as any exercise in which the acquisition of knowledge is the primary goal, and the thing created is the secondary goal. (This may be in class, in lab, at home, or even self-directed, with no school in the picture.) This is in contrast to "work", in which the creation is the primary goal and the learning is the secondary goal. We separate these concepts so we can give advice in cases like yours, and actual code in the other case.Ploch
if you are looking for example code, there is TripleA triplea.sourceforge.net/mywiki/TripleAIlljudged
L
8

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.

Languet answered 28/9, 2011 at 17:41 Comment(0)
F
0

when going with sockets each client will have it's own connection on which a server thread will wait (don't forget to flush the stream on client side or you'll wait forever)

each line will be a separate message and to differentiate the message types you can use a "header" at the start of each message (a specific 3-character sequence at the start) say msg, mov, lgn and use a trie-like selection with switches to quickly decide which one you got


when using RMI you can have the server keep a manager object (exported and registered in the registry) on which a client can request a "connection"-object which will be the same as the connection in the socket implementation but you'll be able to have a method for each thing you wanna do though the callbacks will need to be done in some other way (with sockets you have a connection ready for it)

Fermentation answered 28/9, 2011 at 17:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.