Jump to content

  • Log In with Google      Sign In   
  • Create Account

Data Coordination Between Server & Client


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
35 replies to this topic

#1 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 28 June 2011 - 10:41 AM

I'm working on a game in c++. I've got all the connection stuff set up, client, server, etc., and it runs rather nicely.

Now, I need to know how to best not only coordinate player positions, but when to send what packets as well. So far, I tween player positions when the x,y,z coordinate is close enough, and do a hard set when it's far away. The player data is sent every several milliseconds. Should I be sending key presses to animate the players better? (My game has gravity) What if somebody forges packets and is able to warp to the other side of the map? I need a way to prevent this.

My game also involves bullets, and guns. (It's kind of a FPS) I'd like to make my game fast Posted Image, so I'd like to avoid sqrt(x*x + y*y + z*z) for every bullet, every update. Is there any other way to get around this? I currently keep track of inventory, so packet forging on bullets wont be an issue. (I'm kind of paranoid of this due to the fact that other games have failed miserably from client side programming and cheaters)

Some general pointers or websites would be great.

Thanks.

Sponsor:

#2 Sappharos   Members   -  Reputation: 140

Like
1Likes
Like

Posted 29 June 2011 - 02:51 PM

I can help with one question.

When comparing two distances simply to see which is the larger, you don't need the square root. Use
if (x1*x1 + y1*y1 + z1*z1 > x2*x2 + y2*y2 + z2*z2)
instead of
if (sqrt(x1*x1 + y1*y1 + z1*z1) > sqrt(x2*x2 + y2*y2 + z2*z2))

It may speed up some calculations - in theory. :)

As for forged packets, never trust the client. That is all.

#3 ApochPiQ   Moderators   -  Reputation: 15815

Like
0Likes
Like

Posted 29 June 2011 - 03:04 PM

Moving to the Networking forum, where you're likely to get much better answers :-)

#4 hplus0603   Moderators   -  Reputation: 5342

Like
0Likes
Like

Posted 29 June 2011 - 06:21 PM

Sappharos is right: Never trust the client.

A mechanism that a lot of games use is to send a "baseline" snapshot every 5-10 seconds, and just sending keypresses in between, from the server to all viewing clients.
Meanwhile, for the controlling client to server, only send key presses, and have the server do the simulation and send out the results.
The client can also do the simulation and display to the user, to reduce lag; however, it needs to detect when the server came to a different conclusion than itself, and "snap" the player to the appropriate point.

Typically, this can be done with the periodic baseline updates, if they have a global step number timestep, for example.
enum Bool { True, False, FileNotFound };

#5 Kazzahdrane   Members   -  Reputation: 122

Like
0Likes
Like

Posted 30 June 2011 - 09:50 AM

Are your clients connecting only to one another (Peer-2-Peer)?

I'm not sure how far along you are with the packet sending but a good system to include is a simple debug slider that lets you alter how frequently the "base" update packets are sent (your player positions, etc). This makes it easy to observe how correct your game looks as you add more network traffic - ideally you want to find the lowest frequency of sending data that still looks good. It's possible you may want to have immediate sending of packets with crucial data in them (firing a rocket, end of a game round, etc).

#6 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 11 July 2011 - 08:46 PM

I apologize for the long delay.. I actually got distracted working on my game :D

@Kazzahdrane No, it's not peer2peer, I believe server-client works better in my situation. I currently send packets every 500ms, and it seems to work ok. I'm not sure if this is fast or slow compared to the industry standard.

@hplus0603 What exactly do you mean by baseline? I have my data wrapped up for keypresses, but I'm not exactly sure what to do. Do i send a packet every time a key is pressed, or do I simply update every 500ms or so?

@ApochPIQ Thank you, I'm rather new here.

@Sappharos I've always tried to follow Never Trust the Client. Sometimes I feel as though I'm a bit paranoid. For example, can the client ignore packets? I currently implement a strike system. If someone were to use cheatengine (It's scary stuff for developers) to hack their inventory, and the player tries to use that item, they are dealt a strike. After 5 strikes, the server gives end of stream and disconnects the player. Is that okay?

Also, that algorithm is exellent.. I cant believe I didn't think of that.

#7 Sappharos   Members   -  Reputation: 140

Like
0Likes
Like

Posted 12 July 2011 - 03:43 AM

What if somebody forges packets and is able to warp to the other side of the map?


If you let them, it's safe to assume they will. Any data which could be manipulated to give the player an advantage in the game (position, health, ammo, money or other resources) is sensitive. My personal approach would be not to ban people for hacking the client (as you get more players this becomes less practical, and there's always a possibility of mistakes) but to simply make it impossible for it to confer an advantage to them. So yes, I'd just send a snapshot of the player position every few seconds for the server to check, if it's too far away then correct it. Don't allow the player's ammo to go up unless they've just picked up some, or they're in a shop and there is an appropriate deduction from their money. That sort of thing.

#8 smasherprog   Members   -  Reputation: 432

Like
0Likes
Like

Posted 12 July 2011 - 04:11 AM

I am writing my own game server now as well, and I was thinking of going the same route as you with the strike system. I would log when a player tried to do something impossible, and after so many times, ban the account. However, after thinking about it more, I think that is a bad idea; let me explain why. If the server is checking all requests from clients (as it should), then a client should not be able to cheat. So, I would be banning accounts for probing my server for vulnerabilities. Yes, I would be a bit upset that someone is doing this, but as long as no damage occurs, I should continue to let the client probe --as long as its not causing damage to my system --after all, the client should be paying me money to play. So, as long as I am getting paid, and no damage to the server occurs, let them probe all they want, right? If I ban them, I am out money. If I let them continue, I get money. Better to get paid than not ... right?
Wisdom is knowing when to shut up, so try it.
--Game Development http://nolimitsdesigns.com: Reliable UDP library, Threading library, Math Library, UI Library. Take a look, its all free.

#9 ApochPiQ   Moderators   -  Reputation: 15815

Like
0Likes
Like

Posted 12 July 2011 - 04:33 AM

When clients do something they shouldn't, log it, and discard their input.

Then, patrol the logs periodically. You can even write tools to help with this. If you see a particular client doing suspicious stuff consistently, then you can think about taking action. Until then, the best policy is to just ignore things that shouldn't be done. That way, people can't tell the difference between sending garbage to the server (which should do nothing) and sending legitimate but "illegal" input to the server (which, if they knew it was legit but illegal, could tell them how to further exploit your system).

#10 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 12 July 2011 - 10:07 AM

When clients do something they shouldn't, log it, and discard their input.

Then, patrol the logs periodically. You can even write tools to help with this. If you see a particular client doing suspicious stuff consistently, then you can think about taking action. Until then, the best policy is to just ignore things that shouldn't be done. That way, people can't tell the difference between sending garbage to the server (which should do nothing) and sending legitimate but "illegal" input to the server (which, if they knew it was legit but illegal, could tell them how to further exploit your system).



Sort of like Darwinian Evolution...
That's what I do essentially. Maybe after x number of strikes the server should start making warnings to the admin.
Should I consider basic packet encryption, such as XOR?

#11 ApochPiQ   Moderators   -  Reputation: 15815

Like
0Likes
Like

Posted 12 July 2011 - 10:51 AM

If you're going to encrypt network traffic, do it right (public key systems, preferably on top of an existing SSL style implementation) or don't mess with it. XOR mangling (I wouldn't even call it encryption) only serves to annoy the people you're trying to protect against, and when they get annoyed by your security measures, they tend to redouble their efforts to break those measures.

#12 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 12 July 2011 - 06:26 PM

If you're going to encrypt network traffic, do it right (public key systems, preferably on top of an existing SSL style implementation) or don't mess with it. XOR mangling (I wouldn't even call it encryption) only serves to annoy the people you're trying to protect against, and when they get annoyed by your security measures, they tend to redouble their efforts to break those measures.


Well, I probably wont. Given that I write the server correctly, I shouldn't need to encrypt anything, right?

#13 ApochPiQ   Moderators   -  Reputation: 15815

Like
0Likes
Like

Posted 12 July 2011 - 06:57 PM

I wouldn't consider it necessary unless you are transmitting personal or identifying information about your users, including (but not limited to) emails, passwords, billing information, etc. If you transmit anything that your users don't want stolen from them, spring for encryption.

#14 hplus0603   Moderators   -  Reputation: 5342

Like
0Likes
Like

Posted 12 July 2011 - 09:57 PM

@hplus0603 What exactly do you mean by baseline? I have my data wrapped up for keypresses, but I'm not exactly sure what to do. Do i send a packet every time a key is pressed, or do I simply update every 500ms or so?


Baselining is when you send occasional full state snapshots, and then send input commands in the meanwhile. From the client, you really don't need to send snapshots. From the server, you do, to correct for the unforeseen. Typically, all state snapshots and commands will be tagged with the game step number that they're intended for. Note that sending commands needs that everyone needs to simulate the world at the same rate of steps per second (but can render at different rates).


If someone were to use cheatengine (It's scary stuff for developers) to hack their inventory, and the player tries to use that item, they are dealt a strike. After 5 strikes, the server gives end of stream and disconnects the player. Is that okay?


One strike and you're out, in my book! And a mark is made on your account that you're a cheater. Perhaps even insta-banned. Just make sure you don't have bugs that cause bad-bans :-)

Or perhaps you mark the account for hell-ban. The next time it logs on, it will never find any open servers, or only fake open servers on IP addresses that never actually answer. Or only servers operated by other cheaters -- let them play together!
enum Bool { True, False, FileNotFound };

#15 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 13 July 2011 - 08:29 AM

Alright then, I probably wont.

What would be the best way to handle bullets? I know I need x, y, z, and velocity, but what should I do after that? How should the server handle when somebody is hit? Should the server report to the client that the client was hit, or should the client report to the server that he hit somebody? I've actually seen the second in games --as iffy as it could be.

Baselining is when you send occasional full state snapshots, and then send input commands in the meanwhile. From the client, you really don't need to send snapshots. From the server, you do, to correct for the unforeseen. Typically, all state snapshots and commands will be tagged with the game step number that they're intended for. Note that sending commands needs that everyone needs to simulate the world at the same rate of steps per second (but can render at different rates).


So essentially the client needs to be counting steps? I'm not doing that. What happens when an incoming step doesn't match the current step?

#16 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 13 July 2011 - 04:07 PM

I implemented the base + input as suggested, but it's rather choppy (for both clients) every 2 seconds when the data is sent. Should I be tweening rather than hard-setting? Maybe I should only set it when the expected value and the actual value are far apart.

#17 hplus0603   Moderators   -  Reputation: 5342

Like
0Likes
Like

Posted 13 July 2011 - 06:52 PM

I implemented the base + input as suggested, but it's rather choppy (for both clients) every 2 seconds when the data is sent. Should I be tweening rather than hard-setting? Maybe I should only set it when the expected value and the actual value are far apart.


Yes, tweening for baseline updates is good. Also, some systems run the displayed clients behind in time, such that you will always have the right data for the simulation of each player. You see exactly what they did, but at some point later in time. If that is implemented properly, there should be no snapping, as each baseline should just send you information you already calculated yourself.

As for "who hit whom," that's an entire sub-genre on its own. There are various trade-offs between complexity, response time, what the user sees vs what happens, and openness to cheating. There are links in the FAQ that talk about how various games deal with this (Source and Quake III among the more prominent).
enum Bool { True, False, FileNotFound };

#18 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 14 July 2011 - 03:52 PM

I read through Quake III and Source (I've played both) and it seems pretty straightforward.

One thing I realized is that TCP was a bad idea from the start (it's slow for this). There's only one problem I have with UDP, however. If two clients are connected to a router, how does the server choose to send data to either one of them given that they're not on the same IP as the server? I followed the Quake III doc and have implemented a random ID generated by each client so that the server can tell their data apart, but I'm not sure how to go the other way. The only thing I can think of is for the client(s) to manually port forward everything on a specific port to their machine, but that's a hassle Posted Image and the games I've played don't seem to do that.

Basically, I don't know what happens once the packet gets to a router. If it gets sent to both clients I should be fine thanks to the random ID.


EDIT: Ironically, halfway through attempting to implement UDP, I realized my game must sync large amounts of terrain data, and thus, must have a reliable connection to do so... Posted Image Do I need to remain with TCP? Or should I implement my own method for packet-confirmation? Bullets are something that cannot be spammed (packet wise), and yet other FPS games continue to use UDP. I've branched my source at this point, so I can go either way.

#19 hplus0603   Moderators   -  Reputation: 5342

Like
0Likes
Like

Posted 14 July 2011 - 06:46 PM

EDIT: Ironically, halfway through attempting to implement UDP, I realized my game must sync large amounts of terrain data, and thus, must have a reliable connection to do so... Posted Image Do I need to remain with TCP? Or should I implement my own method for packet-confirmation? Bullets are something that cannot be spammed (packet wise), and yet other FPS games continue to use UDP. I've branched my source at this point, so I can go either way.


An UDP destination is an IP address and a port number, just like for TCP (but UDP port X is independent of TCP port X). Thus, the router can tell the two apart.

You can do your own reliability if you want, or you can use both a TCP connection and a UDP packet stream. The Enet library does reliability over UDP if you want to use that.
enum Bool { True, False, FileNotFound };

#20 roadkillguy   Members   -  Reputation: 100

Like
0Likes
Like

Posted 14 July 2011 - 09:50 PM

You can do your own reliability if you want, or you can use both a TCP connection and a UDP packet stream. The Enet library does reliability over UDP if you want to use that.


Is Enet easily compiled with mingw? I currently cross compile to windows from linux. I'm using SDL_Net.

Do I need variable reception ports on the client? My qualm is that a packet might be on port 2000 and be going to IP 203.53.100.10, but will never make it to 192.168.1.108 like it was supposed to. Each client on the same IP could then have a different reception port and the same sending port, but would have to be port forwarded manually. Maybe I'm not understanding something.




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