Starting to get it, but not - Multiplayer Card Game

Hey everyone, I have gone through many phases of getting into Networking programming and each time I have gone further and further, and have gained a greater and greater understanding (read as “gained a bit more”).

Currently I am trying to make a Multiplayer turn based card game, just a 52 card deck kinda game, and started off with a Multithreaded chat server and am now beginning to implement the card game aspect to it. I so far have made it so that when 2 users connect, the server is able to distribute cards to each client (it actually just gives random numbers as a place holder).

But now since I want multiple games to take place I am thinking of a method to implement this, this is where I get lost a bit because I was thinking I can just create a GameRoom class which will have its own thread and the users will be sent to it and can play the game, however I realize this method is probably not good because it creates a thread per user and game.

I then got stuck on whether I should just implement it that way for a learning experience or to move over to what I believe is the other solution of using NIO and non blocking technique but dont have much information on how to create something with that, anybody have some links or examples, or comments on what I should do?

I do not want to use any libraries although I know KryoNet looks great, I want to make mine from scratch. If i were to use the threaded approach would my solution work of creating a game class and when a user connects to the server, create the user and send it to an open game?

This sounds like you need non-blocking TCP connection. Look into java.nio.channels.ServerSocketChannel and java.nio.channels.SocketChannel. Good luck!!

For a card game, the server probably doesn’t need to run a thread to handle each game (besides whatever threads you need for networking). Likely the state of the game only changes when one of the players takes an action. Each set of clients in the same game has some data structure that keeps track of which players turn it is, what cards are in what piles for that game, etc. When a player plays a card, the data structure changes to reflect this and updates all the clients. In between players playing cards, nothing is happening on the server.

hmm, I am not sure what you mean. What I have no is each player connects to the server and then the server spawns a thread which communicates with that client, and then are you saying have the GameRoom class not extend a thread just maintain whatever is going on in some sort of while loop?

Also another thing I was thinking about was to have each game extend a thread however have each user just be part of a game and let the Game class communicated only with the players whose turn it is, but that would be terrible for implementing a chat system or something like that am I right?

You are only going to need to run a thread for each connection, not for each game. Each connection, the client logs in, sends the data, receives any data, and disconnects. All you need is short little connections that receive and send data.

Yea that is what I currently have but I guess that leaves me with the problem I am having now, where would I handle the actual game? I want the game to pretty much be played on the server side and the clients are just updated with what is going on or send in “commands” of what they want to do, and the server makes sure its okay and then does it…where would I put all of this logic? how would I maintain whose turn it is, etc. I was thinking inside of a GameRoom class but how would this class be implemented?

All the data would be stored server side. It is recommended to store all user data in text files or a database like MySQL if anything goes wrong or you have to restart the server.

Think of it 1 step at a time. A player connects, which code runs? A packet is received, determine what that packet’s purpose is. Is it a chat message? Is it a move? Is it a request for data? You can create your own protocol for how each packet is structured and you can control the logic from there.

hmm I see what you are saying but for this method, each server will have only one game running correct? Although I believe I should get one game working for better understanding and then work on expanding

Each connection should be its own thread. Good luck!

yes, i have each connection within its own thread, but as for handling the game elements is what I am having trouble with. I want the master server to spawn many games, not just one game once 4 people connect. That is what I cant quite figure out how to do.

No you are correct. You spawn a new game once the master server finds 4 people. Spawning random empty games is not the way to go here. What you should do is have each player put his name on the waiting list. Then the master server just notifies him that a game has been created. Until then the player can log out.

yea thats what I was thinking, each user will have its own thread and when it connects to a server it checks if there is an open game, if not it will create a new one and users just get added to that game until it fills up and then it will create a new one etc, but as for handling the game, the game would just be played within its own thread also correct?

Your GameRoom would be 1 thread doing the update part of your game loop (no point in drawing on the server), it will contain a group of GameTables that each represent an individual card game being played.

Yes, I don’t understand why you keep wanting each game to be its own thread. Think of data structures. You want a class called GameTable that holds all the data about the current game and an ArrayList that holds all instances of GameTable. Each connection would spawn a new thread that just modifies the GameTable.

For my multiplayer card game [http://www.ttafo.com/afo.html], which uses KryoNet [http://code.google.com/p/kryonet/], everytime a client sends a message, I queue up a Runnable to handle processing of that message on the server:


public void received (Connection connection, Object object) 
{					
	queue(new ServerReceptionHandler(connection, object, database, server));				
}


public class ServerReceptionHandler implements Runnable {
public void run() {
    //process message
    if (object instanceof StringMessage) {
       StringMessage sm = (StringMessage)object;
       switch(sm.type)
       {
            //
       }
    }
}
}

Clients can create rooms and can also join rooms that already exist. Rooms act as the data structure for handling the games being played in them. They would store things like the random number seed, a list of all the players currently in them, the dealer, whose turn it is etc. When a gameplay message is received by the server, the Room that the client is in is obtained and the appropriate fields are modified and messages are sent to the players in that room to reflect the changes. I use a ConcurrentHashMap to store the players and the rooms:


public ConcurrentHashMap<Integer, Player> playerMap;
public ConcurrentHashMap<Integer, Room> roomMap;

The OP said he doesn’t want to use KryoNet. But that is exactly how I would set up my game.

Oh wow I understand what you mean now ra4king, I just wasnt getting it but now its much more clear as to what you meant, I will work on this and see if I can get it.

@Hsaka, although I am not using KyroNet, that actually helps me see how things would be handled at a higher level which is what I need, thanks!

The simplest way to go about here to is to use ObjectOutputStream and ObjectInputStream and send primitive data and object data. I made my own little framework that simplifies this all with a Packet class that has an ArrayList of all data in that “message” and a PacketIO that sends all these messages in the stream can read it all back into a Packet. You can check out the code over here.

Thanks for that, but I actually decided that I need to stop trying to reinvent the wheel and began using KryoNet which has been working out GREAT, however one question I have had is with sending objects.

As just a basic test, I want the server to send every user that connects 5 cards, So I have a deck class and a Card class with methods in them such as getValue, toString, etc, etc. So I wanted to create a message class DealCard, which contains a card to send…However that would not work, it would not allow me to serialize the Card class.

So what I did was the DealCard class, has int suit, value; which is sent over the network and then when the player receives the DealCard message it creates a card using those values. Is this the way it should be done?

Also I want to store the Players hand and have methods in the Player class to access all of the cards, play them, etc. However if I add all of those methods in the Player class, I will not be able to send it over the network in Kryo will I?

You can send any object over the net that has an equivalent class on the other end.
And sending primitive data is the best way as it will reduce overhead and be just short and simple.