Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Starting to get it, but not - Multiplayer Card Game  (Read 7790 times)
0 Members and 1 Guest are viewing this topic.
Offline Swattkidd7

Junior Member





« Posted 2011-05-28 09:08:00 »

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?
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2011-05-28 10:12:54 »

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

Offline Nate

JGO Kernel


Medals: 145
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #2 - Posted 2011-05-28 10:25:10 »

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.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Swattkidd7

Junior Member





« Reply #3 - Posted 2011-05-28 10:33:33 »

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?
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #4 - Posted 2011-05-28 18:23:51 »

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.

Offline Swattkidd7

Junior Member





« Reply #5 - Posted 2011-05-29 01:53:46 »

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?
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #6 - Posted 2011-05-29 05:20:30 »

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.

Offline Swattkidd7

Junior Member





« Reply #7 - Posted 2011-05-29 08:48:23 »

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
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #8 - Posted 2011-05-29 14:35:39 »

Each connection should be its own thread. Good luck!

Offline Swattkidd7

Junior Member





« Reply #9 - Posted 2011-05-31 00:46:15 »

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.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #10 - Posted 2011-05-31 01:46:46 »

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.

Offline Swattkidd7

Junior Member





« Reply #11 - Posted 2011-05-31 06:38:42 »

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?
Offline zoto

Senior Member


Medals: 4



« Reply #12 - Posted 2011-05-31 11:51:45 »

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.
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2011-05-31 22:21:47 »

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.

Offline Hsaka
« Reply #14 - Posted 2011-05-31 23:38:14 »

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:

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


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
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:

1  
2  
public ConcurrentHashMap<Integer, Player> playerMap;
public ConcurrentHashMap<Integer, Room> roomMap;
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #15 - Posted 2011-06-01 00:10:40 »

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

Offline Swattkidd7

Junior Member





« Reply #16 - Posted 2011-06-02 00:53:08 »

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!
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #17 - Posted 2011-06-02 05:03:39 »

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.

Offline Swattkidd7

Junior Member





« Reply #18 - Posted 2011-06-07 09:40:37 »

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?
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #19 - Posted 2011-06-07 10:11:51 »

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.

Offline Swattkidd7

Junior Member





« Reply #20 - Posted 2011-06-07 10:32:49 »

Actually I realize I already have a list of players on clientside to keep track of Players that are logged in, I think I have an idea of how to do this, I will prob come back soon with problems though  Lips Sealed

hmm right so I guess you can send any object, I was just missing a default no parameter constructor.

I have a design question, how would you handle telling the user what cards he has, and then telling the server which card he wants to play.

I was thinking of re creating the Player object with a list (Hand) which would hold the cards the player has, so server side it will add 13 cards to the Players hand and then tell the client which cards were added and then the client will add them and display them. Then the client side will display the cards on the board and if one of them is clicked then it will tell the server, the server will check and see if the player actually has that card and then notify the game that the user played the card. Also this method would require me to have a "Player object" created for each client also, but I believe I should keep the client as thin as possible, basically just being a Visual of what is happening on the server

Is this how you would do it?
Offline ra4king

JGO Kernel


Medals: 336
Projects: 2
Exp: 5 years


I'm the King!


« Reply #21 - Posted 2011-06-07 22:32:19 »

Yes, to prevent cheating and hacking, it is best if the server has all the logic and the only thing clients do is send back what the user clicked on and typed.

Offline Nate

JGO Kernel


Medals: 145
Projects: 4
Exp: 14 years


Esoteric Software


« Reply #22 - Posted 2011-06-08 00:01:11 »

I was thinking of re creating the Player object with a list (Hand) which would hold the cards the player has, so server side it will add 13 cards to the Players hand and then tell the client which cards were added and then the client will add them and display them. Then the client side will display the cards on the board and if one of them is clicked then it will tell the server, the server will check and see if the player actually has that card and then notify the game that the user played the card. Also this method would require me to have a "Player object" created for each client also, but I believe I should keep the client as thin as possible, basically just being a Visual of what is happening on the server

That is a decent way of doing it.

You can think of the game as a simulation that is running on both the server and the clients. The server simulation has all the information and is authoritative about what is valid, etc. When the server simulation changes, updates are sent to the clients to update their simulation. The client simulations may not have all the information, eg they may know how many cards other players have, but not what the cards are. So, some of the data may need to be "cleaned" or even omitted (eg, in another game the server would know about an invisible character but this info shouldn't be sent to the clients). It may be worth it to use some of the same objects on both the server and clients. Often the same logic is needed in both places. Eg, the client needs to know what are the valid plays for a card so the GUI can make that clear to the user, and the server needs to know that same information to make sure the client isn't trying to make an invalid play. You might be able to come up with some clever coding where the clients' simulations are automatically kept up to date when the server simulation is modified. Your GUI could take a simulation to render. This would also allow you to rendering a GUI for debugging the server simulation.

Offline Swattkidd7

Junior Member





« Reply #23 - Posted 2011-06-08 00:49:01 »

Ahh thank you that makes great sense, I realize that some data may need to be "cleaned" but am wondering if I am doing it properly. When the game is started a user is given a hand (this is just a test it of course wont work like this in the actual game) and that hand is placed in the Player object, however when a user connects it is sent each player object to let it know who are logged in, however I realized that the Player object holds a hand and I dont want the client having access to other players hands so I decided to send it a copy of the Player but with a null hand. Is this what you were referring to?

I was even thinking to just send the Client a String with the player name because it has no reason for having an actual Player object for each player..

**Hmm do you think its better to just create a new Player object on the client side and then fill in its hand through the use of Packets, or would it be even smarter to just have a "Player" object hold the players information and then the GameTable could have a HashMap of <Player, Hand> that way the GameTable will map which player has which Hand, and then if they leave the table they will no longer be tied to the hand because it would make no sense for a player in the Lobby to have a hand correct?

Thanks again for the help guys, I really appreciate it! I know it seems like I am just throwing out so many ideas but I am just trying to get straight what I want to do and see different ways things can be done.

Btw Nate, KryoNet is BALLER! Thanks for it!
Offline Hsaka
« Reply #24 - Posted 2011-06-08 14:49:54 »

I was even thinking to just send the Client a String with the player name because it has no reason for having an actual Player object for each player..

I think it depends on how your game is structured. If you are going for a lobby-style approach with game tables and such, then when a player connects, all the players in the lobby will be sent a message ('Hsaka has entered the lobby' or maybe just an integer representing the number of players currently online). Then a player could make a request to the server to get a list of the names of players online if he wishes to see that. When a player clicks on a table, he would get a message with a list of the names of the players in that table. No need to send objects across the wire when only a subset of the information in them is actually being used by the client.

**Hmm do you think its better to just create a new Player object on the client side and then fill in its hand through the use of Packets, or would it be even smarter to just have a "Player" object hold the players information and then the GameTable could have a HashMap of <Player, Hand> that way the GameTable will map which player has which Hand, and then if they leave the table they will no longer be tied to the hand because it would make no sense for a player in the Lobby to have a hand correct?

On the server, I would just have an array field in the Player object for the hand. The game table would maintain a list of player objects in it. When a player leaves, they are removed from the game table's list and added to the lobby's list. On the client, when the player is dealt a hand, the server sends the hand to the respective player and the client stores it in his own array.
Offline Swattkidd7

Junior Member





« Reply #25 - Posted 2011-07-08 10:15:04 »

Hey guys I just want to say thank you for all the advice you have given, it has helped me make tons of progress on this project.

However, of course, I have another issue. When trying to connect to both TCP and UDP ports I get the error "Connected, but timed out during UDP registration."

This works for local ip 127.0.0.1, but when I use my actual static IP it gets this error. Also I am able to connect to TCP only but its UDP that has trouble. I have also forwarded the proper UDP port and TCP port so I am not sure what could be wrong.

Thanks in advance!
Offline Spoke

Senior Newbie


Medals: 1



« Reply #26 - Posted 2011-07-15 14:34:14 »

However, of course, I have another issue. When trying to connect to both TCP and UDP ports I get the error "Connected, but timed out during UDP registration."

I googled the error and I found this: 
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
      synchronized (tcpRegistrationLock) {
                                while (!tcpRegistered && System.currentTimeMillis() < endTime) {
                                        try {
                                                tcpRegistrationLock.wait(100);
                                        } catch (InterruptedException ignored) {
                                        }
                                }
                                if (!tcpRegistered) {
                                        throw new SocketTimeoutException("Connected, but timed out during TCP registration.\n"
                                                + "Note: Client#update must be called in a separate thread during connect.");
                                }
                        }

                This is code from the Kryonet TCP and UDP client/server library for Java. The error thrown here seems to have some more information. I'm not sure if this helps you but I found it, and you can has it. Note the note: Note: Client#update must be called in a separate thread during connect.

This is the web site it was on: http://code.google.com/p/kryonet/source/browse/trunk/kryonet/src/com/esotericsoftware/kryonet/Client.java?r=69

Silly question: Why do you need UDP for a turn based card game?

Offline Swattkidd7

Junior Member





« Reply #27 - Posted 2011-07-15 23:56:39 »

I googled the error and I found this:  
Silly question: Why do you need UDP for a turn based card game?

Hey Thanks for that! I will definitely look at that and try it out, seems like I will need to connect in a separate thread.

And the UDP isnt needed for the card game, I was just trying it out Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (24 views)
2014-07-24 01:59:36

Riven (22 views)
2014-07-23 21:16:32

Riven (18 views)
2014-07-23 21:07:15

Riven (21 views)
2014-07-23 20:56:16

ctomni231 (49 views)
2014-07-18 06:55:21

Zero Volt (45 views)
2014-07-17 23:47:54

danieldean (36 views)
2014-07-17 23:41:23

MustardPeter (39 views)
2014-07-16 23:30:00

Cero (54 views)
2014-07-16 00:42:17

Riven (54 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!