Jump to content

  • Log In with Google      Sign In   
  • Create Account


Catching illegal movement with partial data


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
17 replies to this topic

#1 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 12 April 2014 - 11:01 PM

In my game the client sends movement updates each time he changes direction (or speed). It works fine, except for one thing: Recently I changed the game so that the client moves in the direction he is looking, and that can change every client frame, so that's a lot of updates.

 

But without sending every update, it's harder for the server to check that the client did not move illegally. It's a multiplayer game, and it's important that the clients can't cheat. With only a subset of the updates, I could check that the distance travelled between two updates is not too great, and that he does not in any of the updates stand in an illegal position. But that does not mean that he did not travel through something that he should not have been able to. But I can not just check the straight line, because that was maybe not actually the way that the client went. I suppose I could forget about checking that he did not go through anything, because if he cheats he will probably stand in an illegal position at some point.

 

Any ideas?



Sponsor:

#2 Wavarian   Members   -  Reputation: 695

Like
1Likes
Like

Posted 13 April 2014 - 12:45 AM

Can you give us a little more information about your game? What genre is it? Is it an FPS or top-down space shooter?

 

How fast is the player able to turn, i.e. is it possible to turn 360 degrees in a single frame (due to mouse-sensitivity etc)? If so then aim-botting is a possibility and you'll need to implement some sort of accuracy counter which measures how well someone is playing and deciding whether they're just good players or if they're cheating.

 

Since it's a multiplayer game maybe you could implement some sort of democratic system where the server gathers the information from each client as to what it thinks has happened, discarding the outliers, and then sending out the decided game state to everyone. You could also have game clients report collisions that it has witnessed to the server:

 

Client A: I saw client B get hit by an asteroid!

Client B: I didn't get hit.

Client C: I also saw client B get hit by an asteroid!

 

Server: Client B got hit.

 

This of course depends on the number of people playing at the time; if there's only 2 players, and one (or both!) is cheating then it won't work.

 

What you should really do is have the server play along and have it do its best at predicting what is happening and sending out its view to all the clients. At low latency this would work well but at a higher latency (170ms+) it'll become increasingly obvious to the player and possibly unplayable for them with 'snap-backs' etc,


Edited by Wavarian, 13 April 2014 - 12:49 AM.


#3 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 13 April 2014 - 01:01 AM

It's an MMORPG. Aimbotting is not a problem. The amount turned does not matter. The server is the arbiter always. The movement is similar to that of World of Warcraft, i.e. the player's forward movement is in the direction he is looking. The only problem is that if the client does not send all the information, because it's too much, then the server cannot judge perfectly if the player is cheating or not. So, what's the next best thing?


Edited by tufflax, 13 April 2014 - 01:04 AM.


#4 Angus Hollands   Members   -  Reputation: 695

Like
0Likes
Like

Posted 13 April 2014 - 07:19 AM

Depending upon what sort of RPG you're developing, it might be best to send waypoint information rather than direct movement updates. This way, you only need to send updates when the player changes its point of interest. How the client gets from one place to another is less important, so long as the server allows it to do so. 



#5 hplus0603   Moderators   -  Reputation: 4960

Like
0Likes
Like

Posted 13 April 2014 - 11:12 AM

You can (and probably should) send information about more than one time step in a single network datagram.
Use fixed time steps in your physics engine.
Number steps in "steps since time 0" rather than seconds or milliseconds.
Mark each packet with the first time step at which it contains data -- "this packet contains data starting at time step 14020"
Now, each command/input can be executed in order in the server.
If you don't care about deterministic playback, you can omit the time step number in the packet, and just put all the input commands in a queue for the player entity, pulling one set of timestep commands from that queue for each timestep of simulation on the server.
enum Bool { True, False, FileNotFound };

#6 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 13 April 2014 - 12:54 PM

Depending upon what sort of RPG you're developing, it might be best to send waypoint information rather than direct movement updates. This way, you only need to send updates when the player changes its point of interest. How the client gets from one place to another is less important, so long as the server allows it to do so. 

The player does not click to move, so that would not work.

 

You can (and probably should) send information about more than one time step in a single network datagram.
Use fixed time steps in your physics engine.
Number steps in "steps since time 0" rather than seconds or milliseconds.
Mark each packet with the first time step at which it contains data -- "this packet contains data starting at time step 14020"
Now, each command/input can be executed in order in the server.
If you don't care about deterministic playback, you can omit the time step number in the packet, and just put all the input commands in a queue for the player entity, pulling one set of timestep commands from that queue for each timestep of simulation on the server.

I'm using TCP for now. But I have not tested it, so I don't know if I'll change it later.

 

Anyway. The server runs at 10 FPS. But the client can run at 100+ FPS, or whatever really. And, if that was not clear, the player moves instantly on his own client to make the game feel more responsive, but the server checks the movement later. If I would somehow limit the FPS when it comes to movement, it would not feel as smooth as it could, so I don't like the idea of using fixed time steps. I don't use a physics engine, and don't quite know what would qualify as one. But even if I used fixed time steps, they would probably have to be shorter than 0.1 s (the steps the server use). And besides checking for cheating, more than 10 movement messages per second is unnecessary.

 

Right now I think that just limiting the messages sent from the client, and on the server just checking that the client does not move too fast, and that he does not stand in an illegal position at any update, is the best solution so far. He could cheat by walking through a wall, for example, but it seems unlikely that, if he does not move too fast (which is checked for) he will not at any update/message stand in the wall.


Edited by tufflax, 13 April 2014 - 12:56 PM.


#7 0BZEN   Crossbones+   -  Reputation: 2004

Like
1Likes
Like

Posted 13 April 2014 - 06:13 PM

What you have isn't really server-authoritative, therefore not secure. You need to send all the inputs of the clients to the server, as well as the client's predicted position every now and then, so the server can correct the client if needed. If you send partial inputs, you leave yourself opened to exploits. If you send all the inputs, then you know exactly what the client tried to do, where it landed, and if you need to send a correction. Then the client can 'rewind' his input stack, and correct himself.

 

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

 

Client->server bandwidth is at a premium but luckily, if the client only has to send inputs, commands, and sometimes positions, that bandwidth usage is actually very low, even at 100hz. Do the maths, see how much data that actually is. e.g. 100 fps x 100 byte / input = 10kbytes / sec = 80 kbits / sec (plus TCP packet overheads). Secondly, since you will send your inputs reliably, you can use compression techniques to further reduce that bandwidth. 

 

And since you use TCP, if you start sending too much too fast, the TCP frame will drop (i.e. the send() command will not complete, or will block). But in any case, short of a network issue, you should be easily be within the bandwidth limitations of home broadband. What you can do in case your TCP stream starts breaking up, is pause the game on the client side, to let the stream recover enough. 


Edited by 0BZEN, 13 April 2014 - 06:14 PM.

Everything is better with Metal.


#8 hplus0603   Moderators   -  Reputation: 4960

Like
0Likes
Like

Posted 13 April 2014 - 08:19 PM

The server runs at 10 FPS. But the client can run at 100+ FPS, or whatever really.


Rendering frame rate and simulation frame rate doesn't need to be the same (and often isn't.) Best practice for action-like games is to fix a simulation tick rate, and run that rate on both client and server.
There are many other ways of creating a fun networked game, some of which have different trade-offs in consistency, latency, cheat resistance, ease of implementation, etc.
enum Bool { True, False, FileNotFound };

#9 jefferytitan   Members   -  Reputation: 1651

Like
0Likes
Like

Posted 13 April 2014 - 08:56 PM

I am by no means an expert, but if you want some checks without a fully authoritative server I'd suggest something like:

  • Check that the items and effects that they claim to have are possible, which should be server authoritative. For example they exist, are not owned by others, haven't expired or been destroyed, aren't on cooldown.
  • Calculate the max distance they could travel since last state with the current items and effects.
  • See if their new position is within that max distance. This could be as the crow flies, or a coarse graph-based check.

Having said that, no heuristic beats an authoritative server, so it really depends how big a problem cheating is likely to be for your style of game. The other point is that you don't need to catch every cheat, only game-breaking ones or a high enough percentage of cheats that a cheater will be caught and punished within a reasonable timeframe.



#10 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 13 April 2014 - 11:46 PM

 

The server runs at 10 FPS. But the client can run at 100+ FPS, or whatever really.


Rendering frame rate and simulation frame rate doesn't need to be the same (and often isn't.) Best practice for action-like games is to fix a simulation tick rate, and run that rate on both client and server.
There are many other ways of creating a fun networked game, some of which have different trade-offs in consistency, latency, cheat resistance, ease of implementation, etc.

 

What would I include in those simulation frames, and what would be updated every rendering frame? And also, if I could not actually change my position faster than the simulation ticks, what would be the point of updating the rendering?

 

What you have isn't really server-authoritative, therefore not secure. You need to send all the inputs of the clients to the server, as well as the client's predicted position every now and then, so the server can correct the client if needed. If you send partial inputs, you leave yourself opened to exploits. If you send all the inputs, then you know exactly what the client tried to do, where it landed, and if you need to send a correction. Then the client can 'rewind' his input stack, and correct himself.

 

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

 

Client->server bandwidth is at a premium but luckily, if the client only has to send inputs, commands, and sometimes positions, that bandwidth usage is actually very low, even at 100hz. Do the maths, see how much data that actually is. e.g. 100 fps x 100 byte / input = 10kbytes / sec = 80 kbits / sec (plus TCP packet overheads). Secondly, since you will send your inputs reliably, you can use compression techniques to further reduce that bandwidth. 

 

And since you use TCP, if you start sending too much too fast, the TCP frame will drop (i.e. the send() command will not complete, or will block). But in any case, short of a network issue, you should be easily be within the bandwidth limitations of home broadband. What you can do in case your TCP stream starts breaking up, is pause the game on the client side, to let the stream recover enough. 

If I'm gonna send stuff every frame, I might as well just send the position and direction, because as long as the server checks for speed and collisions, it's fine. No? And it's easier for the server to do that.



#11 0BZEN   Crossbones+   -  Reputation: 2004

Like
0Likes
Like

Posted 14 April 2014 - 07:02 AM

What you send is what you need for the client-side prediction to work. i.e. position, velocity, orientation, inputs, some special action buttons (fire, jump, ect). Just be careful because all that adds up to a lot of data if you do it naively. 

 

And BTW, you don't need to send prediction info with every input frame. Just once in a while so the server can correct the client-side prediction. 


Everything is better with Metal.


#12 hplus0603   Moderators   -  Reputation: 4960

Like
0Likes
Like

Posted 14 April 2014 - 09:33 AM

if I could not actually change my position faster than the simulation ticks, what would be the point of updating the rendering?


You can render an interpolated version of the world. Popular console FPS games may run at 30 or 60 Hz for rendering and physics, but typically runs networking at 10, 12, or 15 Hz.
For a sketch, see the canonical game loop: http://www.mindcontrol.org/~hplus/graphics/game_loop.html
enum Bool { True, False, FileNotFound };

#13 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 14 April 2014 - 03:33 PM

 

if I could not actually change my position faster than the simulation ticks, what would be the point of updating the rendering?


You can render an interpolated version of the world. Popular console FPS games may run at 30 or 60 Hz for rendering and physics, but typically runs networking at 10, 12, or 15 Hz.
For a sketch, see the canonical game loop: http://www.mindcontrol.org/~hplus/graphics/game_loop.html

 

I have interpolation for other players. But interpolation (or extrapolation) for the player himself, surely that must be noticeable. And besides this problem (sending a lot of movement information) I have no need for a simulation frame rate that is different from my rendering. Maybe extrapolation would work OK if I ran the simulation as 20 FPS or something. Hm...


#14 hplus0603   Moderators   -  Reputation: 4960

Like
0Likes
Like

Posted 14 April 2014 - 03:46 PM

But interpolation (or extrapolation) for the player himself, surely that must be noticeable


Old versions of Quake ran the physics at whatever your screen refresh rate was.
The end result was that the physics simulation would let you reach certain ledges/heights when your frame rate was high, but not when it was low.
This is not a good way to make the game fair in multiplayer :-)

Every game is different. That being said, good defaults are to:
- fix your simulation time step
- run input and simulation at 60 Hz (good initial estimate)
- send packets at 20 Hz
- render the scene unlocked from physics -- your choice if you want to interpolate and render faster than physics, or stop at 60 Hz

You can also run input faster than physics, but queue input for the next simulation tick. If you update the *camera* (for turning) faster than simulation, that will not affect simulation, and thus will let you appear to give a faster response time to input at high frame rates, while still getting all the benefits of a fixed simulation rate.
enum Bool { True, False, FileNotFound };

#15 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 14 April 2014 - 04:58 PM

 

- run input and simulation at 60 Hz (good initial estimate)
- send packets at 20 Hz

 

So would I just send 3 input states per packet, or what's the difference between these two rates?



#16 0BZEN   Crossbones+   -  Reputation: 2004

Like
0Likes
Like

Posted 15 April 2014 - 07:46 AM

 

 

- run input and simulation at 60 Hz (good initial estimate)
- send packets at 20 Hz

 

So would I just send 3 input states per packet, or what's the difference between these two rates?

 

 

 

Less packet overheads (in UDP anyway).


Everything is better with Metal.


#17 hplus0603   Moderators   -  Reputation: 4960

Like
1Likes
Like

Posted 15 April 2014 - 09:39 AM

So would I just send 3 input states per packet, or what's the difference between these two rates?


Yes. Additionally, when receiving the packets, you would queue them for processing -- not just apply all three at the same time step.

This means that the latency introduced by networking is BOTH the batching latency (because the packets are queued on receipt) AND the transmission latency. This is a fact of life, pretty much :-) It's possible to build networked games that send all the packets all the time, and it may provide slightly lower overall latency, at the expensive of significantly higher server overhead. Additionally, you need to be able to compensate for transmission latency anyway, and thus you might as well use that same mechanism to also compensate for batching latency. The server-side overhead of high packet rates is significant!
enum Bool { True, False, FileNotFound };

#18 tufflax   Members   -  Reputation: 475

Like
0Likes
Like

Posted 15 April 2014 - 02:27 PM

I see. Still, 60 updates per second seems like a lot, hmm...

 

Thanks guys! You have given me things to think about.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS