2
\$\begingroup\$

I'm thinking about programming a multiplayer game. For communication, I will use a Server <-> Client design like the following:

Client <-> Server <-> Client

The Game will be a kind of Tower Defense. Where two players can fight each other by sending soldiers to the enemy to destroy their base or build towers to defend.

To keep the games in sync, each action must be sent to the other player.

e.g. Player 1 set a tower on position x, y so Player 2 must know about this tower (It would be pretty unfair if the enemy has invisible towers)

To sync the two games I can think of two methods:

First method:
The client(Player 1) set a tower to position x, y and send a message to server: "I have placed a tower on position x, y". The server sends this message forward to the other client(Player 2)

//client 1
buildTowerOnPosition(x, y);
sendToServer(BuildTowerMessage(x, y))

//server
receiveMessageFromClient(BuildTowerMessage(x, y))
sendFurtherToOtherClient(BuildTowerMessage(x, y))

//client 2
receiveMessageFromServer(BuildTowerMessage(x, y))
buildEnemyTowerOnPosition(x, y)

By this method:
The server doesn't need to know the current game status and serves only as a bridge between the clients

Second Method:
The client(Player 1) send a message to server: "I will build a tower on position x, y" the server build a tower to position x, y and send the changes(New tower on position x, y) to the clients

//client 1
sendToServer(BuildTowerMessage(x, y))

//server
receiveMessageFromClient(BuildTowerMessage(x, y))
buildTowerOnPosition(x, y)
sendFurtherToBothClients(BuildTowerMessage(x, y))

//both clients
receiveMessageFromServer(BuildTowerMessage(x, y))
buildTowerOnPosition(x, y)

By this method: The server needs to know the current game status

My thoughts are:

By the first Method
The server only needs to forward the message and the main calculation is on the client side which relieves the server.

By the second Method:
The server can control the actions of the clients. For example: When both players set a tower on the same position at the same time, the first tower will be set and the second cannot be built anymore.
In the first Method the second tower will overbuild the first or in the worst case, both clients have different towers.

Now to my question:
Which method should I use for my game?
Is there more pro and contra by the methods?
Are there other methods?
Are there kinds of games where I should prefer another method than in my game?

Thank you for your advice

\$\endgroup\$
3
\$\begingroup\$

In Multiplayer games, it is usually good to have the server be the authority. This will solve many (but of course not all) problems with network issues, cheating and so on.

You already mentioned part of it in your question: if the clients do all the work and the server only relays messages without checking them, you can get all kinds of inconsistencies if things happen at the same time or close to that. If one or both of the players has a spotty internet connection, all bets are off. And this only gets worse if you include cheaters into the equation - it's a lot easier to convince your own client that you have infinite money and just built 417 towers than to convince a server that effectively runs the game. Not to say that it's impossible to deal with this kind of thing any other way, but it is a bit easier if the logic is done in one place, by a server you control.

Of course, this is also means a bit more work. Some cases, like building a tower at the same place, should be caught without adding much code (I assume you check if it can be built there anyway). To prevent/mitigate other issues, you might have to do some sanity checks and validation on the client messages you receive, and you'd need to handle messages that might arrive in another order than they were sent in due to network issues, or messages being lost completely. The same goes for the client - you might need to make sure that it stays in sync with the state as the server sees it.

As for other methods: if the server only relays one client's messages to the other anyway, an alternative might be to have a direct connection between clients and skip the server part completely, or only use it for finding and joining a game. It would work out basically the same, because you'd need to validate and process messages on the client anyway.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks for your advice. You said a few good points to consider. \$\endgroup\$ – Morchul Jun 21 '18 at 11:18
  • \$\begingroup\$ Thanks. Take it with a grain of salt though - I've never actually done a multiplayer game myself. What I said is purely theoretical :) \$\endgroup\$ – Christian Jun 21 '18 at 13:04
2
\$\begingroup\$

I would advice not to invent the architectural wheel but the read the networking documentation for well-known engines such as Unity or Unreal and to see how they designed the things to work.

Regarding your question, about which method to use.

Same as @Christian, I would advise to the server to hold the authority and double check things that player are trying to do.

You need to answer the question: "Do I want cheaters in my game spoiling other people experiences?"

If the answer is no, then you need to double check everything, and server should hold the entire state of all the game worlds and double-check it with the clients actions and state. Clients should be merely the view, a reflection of the server state, but only server should tell what can be done and send appropriate commands to other clients.

For example, in the first variant of your message system, the malicious player could just spam your server with fake "I've build a tower" messages, and by merely replicating 'em, you will spoil other players experience.

\$\endgroup\$
  • \$\begingroup\$ Thanks, I think that I don't invent the architectural wheel with these two methods. But it's a good idea to read the doc of someone who has done this already. Do you have an example of networking documentation of a well-known engine, which you understand without being a pro? \$\endgroup\$ – Morchul Jun 21 '18 at 13:32
  • \$\begingroup\$ Maybe I used wrong phrase. I was not going to make you feel like your ideas are bad, it's just that it's a passed stage or something like this. I'm pretty sure some very old online games had patterns you mentioned in your question. Documentation, yes: docs.unity3d.com/Manual/UNetOverview.html \$\endgroup\$ – PaulD Jun 21 '18 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.