Advertisement

How much should be done on the server?

Started by March 19, 2015 02:29 AM
1 comment, last by hplus0603 9 years, 8 months ago

I'm in the process of trying to write the networking for a small FPS project. I've got remote procedure calls and replication of objects already, but I'm trying to decide on what the best way to handle player input and prevent cheating is. It's client-server with one of the players as host, and I might also set it up to work with dedicated servers. Right now I've got each client calculating movement and hit detection and sending its position and damage requests to the server. Everything I've read says that client data should never be trusted though, so I want to fix the architecture I've got.

With client-server games, is movement, hit detection, damage, etc. ALL calculated on the server? Like do I just send the input to the server and wait for the results from it? Or is some of the work done on the client too?

Generally you do the work on both, but the client's version of the work is only a predicted gamestate, which is used to make it look like there's zero latency.

e.g. the client clicks to shoot a bullet. They send a message to the server, requesting to shoot this bullet. In the meantime, while waiting for the server's response, they continue to run their own simulation, showing the bullet firing, sparks coming off a wall, etc...

Eventually the server responds by telling the client that yes, they did shoot a bullet at X point in time.

OR

The server responds with a game-state in which the bullet was never fired (maybe another player stunned the client first), so the client needs to rewind their predicted gamestate and adjust it to show the server's version of events.

Some required reading:

https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking

http://trac.bookofhook.com/bookofhook/trac.cgi/wiki/Quake3Networking

Advertisement
The typical FPS architecture runs the same simulation on client and server. Player commands (inputs) are sent to the server -- this means actions (throw grenade, run forward) and controls (aim left.) Visual effects of firing weapons and throwing grenades will be shown on the client right away, to reduce the feeling of lag. The server will then use the unified server view to actually simulate the outcome. Physical effects of hitting players, causing damage, etc, will be sent as events from the server to each of the clients. Note that this is *all* based on events (typically time-stamped to a particular simulation tick.) "RPC" is only used insofaras it is a convenient wrapper for asynchronous events -- typically, RPC will not actually return a value; that kind of synchronous RPC is not a good match for action games for a variety of implementation and network related reasons.

The question that then arises is: There is latency in sending player data along. If I see you on my machine, and I fire at you, it may look like a clean hit on my machine, but on your machine, you had already turned left, and would not have been hit by a bullet fired in the particular direction I fired. The truth on the server is somewhere inbetween. How to resolve this? There are three basic options:

1) Always use the server view, and display remote clients "behind time," and players will learn to "lead shots" compared to where other players are running. What everyone sees is actually things that happen. Cheating is not possible. (Other than local assists, like transparency hacks, aimbots, etc.)

2) The client sends the position and last-received time-stamp of the hit target to the server. The server puts the indicated target back to that point in time, essentially emulating what the client "would have seen," and indicates hit if the client is not lying. Cheating can be done by acting on "old data," some players used a network cable with on/off switch to buy themselves a few seconds when they needed it.

3) Forward-extrapolate the display of remote players. This means players will aim "better" as long as the forward extrapolation is correct, but it means that players will "miss" when the entity they are aiming at actually turned so the extrapolation was wrong. This can also be combined with making hit geometry larger the faster someone is running, as well as reducing the possible turning radius the faster someone is running. This shares many properties with option 1, but displays differently and thus looks "much better" 90% of the time, and "much worse" 10% of the time.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement