5
\$\begingroup\$

I'm trying to write a multiplayer game where players join small matches with other players. What I also want is a way for players to login and go online. How would I design the a server that could handle logging in, matchmaking and the actual running of the match? I'd like to have multiple threads on the server to handle input from all the players, but I'm not exactly sure what I want to put in a single process and what I want to split apart. How would I set up the sockets for something like this?

I'd probably end up having this run on Amazon EC2 or something similar if that makes a difference.

I was planning on making the game a MOBA where there would be a small number of players (6-10) and latency would be relevant.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ The correct answer depends on two things. How many concurrent players per server and per match? Is the game near realtime like an fps, or does latency not matter, like in a card game? Bryan's answer is correct for a small number of concurrent players in a game where latency is irrelevant. \$\endgroup\$
    – Peter
    Jan 3, 2016 at 22:11
  • \$\begingroup\$ @Peter is right; if you want to your servers to handle thousands of players, or deal with latencies, the things become much more complicated :-( . See, for example, my recent post on server-side MMO architectures: ithare.com/… \$\endgroup\$ Jan 4, 2016 at 10:38

2 Answers 2

6
\$\begingroup\$

Depending on what language you are using, the answer can vary.

However, if you know any Java, or can at least get the gist of it, here's some old code I wrote to handle something like this.

https://github.com/TheDudeFromCI/WraithEngine/tree/5397e2cfd75c257e4d96d0fd6414e302ab22a69c/WraithEngine/src/wraith/library/Multiplayer

Basically it works like this. First, on your server, wherever it's being hosted, you have it open a socket on a port you choose. This should go on a dedicated thread, and handle ONLY this task. This should always be open, and listening for anyone trying to connect. When someone finally does connect, create a new dedicated thread, with a socket connecting to that client. When that client loses connection, (logs off, or force quits) kill the thread.

For the client, it's even simpler. Just have 1 thread, and have it try to connect to the server ip, (if you have only one server, hard code it in. If multiple, then you can have the player type it in.) And use the same port as you chose for the server. If a socket is able to be opened, connect, and that thread will be dedicated with chatting with the server. If you want to avoid delays in gameplay, this should not be your main thread, but in addition to. Then when a message is sent or received, pass it asynchronously to the main thread. To avoid stalling, make sure the main thread is never "waiting" on the server thread. (A waiting screen is fine for times where waiting is needed, because it doesn't cancel rendering events, or input events. So the program won't be marked as unresponsive.)

Now you should be able to handle an infinite number of new clients trying to connect.

Now, each thread is a seperate client. So keep these all in a list. Most likely in some kind of thread wrapper to handle easier packet sending and receiving. If you want some security, use a handshake packet. This means that the server "asks a question" sort of speak, and if the client doesn't answer, or answers incorrectly, it kicks them. Also, banned ips should be kicked before even the handshake.

Now, in your list of clients, wait for a match request to be called, however you want to do that, then take those clients that request it to be moved into a queue. Once you have enough players, start a match with that list of clients. When a packet is received, send it back to all other players in the list. For example, a player moves, a packet is sent, the server receives it, and sends it to all other players in the list, the render the move, and poof. If that's not fast enough, you can have players actually act like mini servers, and connect to each other fully. This will make pings twice as fast, but may be harder to detect hacking. So be careful.

Once the match is over, send a packet to the clients saying the match has ended, and make their clients render a game over screen when that packet is received.

I hope all of that makes sense.

\$\endgroup\$
1
\$\begingroup\$

Assuming you want to design the server in Java, I would like to add in few more points or suggestions using one of my old answer.

Firstly you will require to learn Java Sockets. It is through which you can connect various clients to the server and exchange data. Once you are done learning the basics of Java Sockets, then you can go on and use a library like Kryonet or Netty.

Kryonet allows you to send data using Serialization which it achieves by Kryo serializer. Let's say if you are making bomberman and you want to send x, y location of your player to the server. You can create a class called Position with x, y variables and send an object of the class to the server. When Server receives the object you can then send it to other Clients connected on your game Server. You can store connected clients into a static List or some other data structure. I use HashMaps.

Now let's say you do some other action like shooting or anything you will create an object of the relevant class and send it to the Server. Then you can code your server on how to process these class objects.

Also let's say 100 clients are connected to your game server. You don't want to process events from every client on a new Thread. This won't scale well. You will also have to learn about Blocking and Non Blocking IO where you will understand how to handle so many clients at the same time. (Kryonet does that using Non Blocking IO)

You will also have to decide what kind of protocols you are going to use like TCP or UDP etc. It is a vast topic but for starters I would say that you should start simply by first Learning Java Sockets and creating a basic Chat Server and Chat clients and then proceed from there on. Firstly build it using Blocking IO and then using Non Blocking IO.

As far as Netty is concerned it is very vast and has a steep learning curve so you can ignore it for now.

Multiplayer games are not easy and there is a steep learning curve

You can read articles on this website for more information. Gaffer on Games

Here is a tutorial on Blocking vs Non Blocking IO

Here is a tutorial on Java Networking

Tutorial on Kryonet

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .