I'm currently planning a simple online multiplayer game. And here is the question. Does it make sense to make the whole game logic on the server and just send the input from the client to the server? Which are the pros and the cons or are there any reasons why I shouldn't do that?
5 Answers
You don't want to send player input to the server. What you probably want to do is send an abstracted representation of what the player wants to do to the server, and then run the logic on there.
Likewise you don't necessarily want to send back everything the client needs to do. For example, you can send some kind of message saying "NPC X died", and the client determines what animation/sounds to play. Stuff like that.
The trick is to find the line where bandwidth and processing power (on the server) is trumped by preventing people from cheating. Usually you make any kind of game-changing authoritative decision on the server only, and leave all the ancillary visual stuff to the client.
There are a lot of more specific questions on this topic all over the site. For example:
Should collision detection be done server-side or cooperatively between client/server?
Who does the AI calculations in an MMO?
Should the game host be the authority, or another dumb client?
-
4\$\begingroup\$ +1 Beat me to it. Also, depending on the style of game, you may want/need to do some client-side prediction. \$\endgroup\$ Commented Nov 30, 2011 at 19:32
Well, you got answers but your real answer is at "try yourself". The things differ from game to game.
I did couple of multiplayer games for some distributed network game design course. The most challenging was doing a realtime action game where many players involved and sending inputs like hell. When it comes to that point, everything becomes problem. As you see the first link Tetrat sent, even determining a collusion becomes a problem. And you will read-hear terms like lag, interpolation, extrapolation, prediction... But if you never tried yourself coding from scratch, you will just accept these words and wouldn't know what they really mean.
My recommendation is:
Step 1
Just start with fully authorized server based design for now. As you said, just send user inputs to server and let server do everything and clients get the results. Your game will work fully consistent. But when you look at your clients, you will notice some lags, some teleport problems, not smooth movement...ect.
Step 2
Start fixing the issues on client side. The teleporting problems for example. Your character was at (0,0) and server said now you are at (100,100). Your character will just teleport to (100,100) which is not nice. There comes the interpolation. You should have a code in client side which will slide the character from (0,0) to (100, 100) in a smooth way. Yes, you will move your character from (0,0) to (100,100) but how fast? For now you can just use the time difference between each server update. If your server sends 10 packets in a second which means 100 ms delay between each packet.
Step 3
Now your game is already good for fast networks where there is delay of (1-50)ms. But it gets doomed if there is a packet loss, high latency or calculation takes long in server...ect. In those situations you will notice when you press left arrow, you will see your character moving left with a delay of 200 ms. The delay between your packet goes to server, calculation time and comes back to you with your last position. This is bad, the worst disadvantage of server authorized design. Player wants his character move left as soon as he presses left, you can't make him wait. Luckily client also have the same code as server, so why not execute it on client immediately and fix the final result with the answer from server? Thats what basicly input prediction is. Client presses left, the code in his side will move him to left, after some time lets say 200 ms, the real position comes from server and client corrects its position with it. If everything went allright, client won't notice anything, "step 2" will also help us with this.
Well, net has many tutorials and things about this subject. But there are 2 I really like:
Really good, covers dark spots: Valve-Source Engine Multiplayer Networking
Kind of history, fun to read and worth it: 1500 Archers on 28.8 ,
Pros:
- this approach is more (most) piracy proof
- you can apply updates more easily
- centralized community
Cons:
- huge bandwidth requirements
- some users can hate that approach (privacy and stuff)
- problems with local gameplay (LAN parties), singleplayer
-
\$\begingroup\$ The problems with LAN gameplay can be avoided by providing a dedicated server binary or allowing one of the clients to act as server. A solution that fixes both single player and LAN problems would be to transparently host a server on the client computer (if it's only a single player game, there shouldn't be any significant difference in computing power between this approach and a traditional binary). This may not work for all game types \$\endgroup\$ Commented Dec 1, 2011 at 5:42
Server side logic also creates scalability problems - you have to do all the work for all the clients on your server - verses letting each client do his own share of the total work.
-
\$\begingroup\$ It's funny when I asked similar questions here in 2016, everyone just told me "never trust the client". \$\endgroup\$– newguyCommented Nov 28, 2016 at 8:44
-
\$\begingroup\$ It depends on the game, but clients cheating themselves are not a serious concern, and clients cheating against other, honest, clients; whatever the server might have done to not trust the client, the honest clients can do instead. \$\endgroup\$– ddyerCommented Dec 2, 2016 at 7:53
Depends on what game you want to create and what part of the game. If developing an RTS (or any game with a lockstepped model), then you definitely should only send the input and which simulation step the input was recieved.
If you want to do a shooter you could use both input and abstract functions. If you take Unreal Tournament 3 as the case, they created the multiplayer mainly via replicated function calls.
For movement they take the player input( compressed into a single bit for each action) delta rotation, acceleration & timestamp and send it to the server.
For other purposes like weapon they synchronize when you shoot (AFAIK, havn't looked into this part in depth yet).
For more static / less often changed values like health they send the variable to the client or server depending on what the programmer specified.
And for non-RTS games, remember client prediction.