Jump to content

  • Log In with Google      Sign In   
  • Create Account


FPS Network Architecture


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

#1 Arjan B   Members   -  Reputation: 582

Like
0Likes
Like

Posted 23 August 2011 - 02:34 PM

Hey forum!

I've been wanting to create a multiplayer FPS.
For the network part I've come up with the following:


There will be one central server, acting as a lobby. All clients can connect to this server and request a list of games being hosted. A client can then pick one of those games and request the server for the needed information to actually join the game.
Every game is hosted by one player, the host. The host will act as the central point connecting all the clients in the game. The hosts gamestate is the one true gamestate, ie when one of the clients disagrees with the host's gamestate that’s too bad, because the host is the boss around here.
Whenever a client provides input for the game (such as clicking a mouse button, moving the mouse, pressing a key) this input is sent to the server, which in turn sends it to all other clients.
To provide some illusion of smooth motion, gamestates are updated locally according to the locally known input states. But there is always some difference in time between actual input and the arrival of a message notifying about this input. That’s why these messages should have some sort of timestamp, so that when receiving an update on input we can handle it as if it really happened at that point in time. To make this happen, we need to keep a buffer of gamestates so we can make the update in a previous gamestate and recalculate the new gamestate.

But now I'm still having some questions:

  • What sort of timestamp should I use? A simple counter that starts at 0 and increases at, for example, 60Hz? How do I synchronize this counter for all clients?
  • Would it be okay to handle some collisions only at serverside? Such as a bullet hitting a player or a player picking up a health pack. Server sends a message that it happened and voila, it happened everywhere. Else I'd have to implement some kind of query "Did I pick up this health pack?", which seems an inferior choice.
  • How long should I keep old gamestates? Discard anything before the oldest update of all of the players? But what if somebody in the game is AFK for 15 minutes, that would make everyones buffers grow pretty big. Maybe send an obligatory status update every 2 seconds or so?
Thank you in advance,
Arjan

Sponsor:

#2 rip-off   Moderators   -  Reputation: 7661

Like
0Likes
Like

Posted 23 August 2011 - 03:48 PM

Question 12 in the Forum FAQ has links to how some real games solved these issues.

#3 saluk64007   Members   -  Reputation: 156

Like
0Likes
Like

Posted 23 August 2011 - 06:36 PM

I could be wrong about these things, but this is how I see it:

1. You shouldn't need to syncronize clocks. The host will probably need to timestamp its gamestate, the client can use the latest received timestamp when buffering inputs to send - i.e., I pressed the "up" key when my gamestate was 1001.

2. Bullets are hard. You need to balance "My shot was obviously lined up, so he should take damage" with "theres no way that guy could have hit me". And then of course the host has to be authoritative on the bullet or clients will send fake "I hit this guy" messages. If your states are pretty well in sync, make sure that the shooter tells the server: A) where he thought he was when he fired, and B) what state he thought the other players were at when he fired. If you are handling bullets as physical objects, you should then be able to place it at the right place and going the right direction at the right time so that it makes sense to all players. If it's not a physical object, you can do hit detection on the server side and arbitrate damage as well. I'm sure you will still have fun with this one even if you do all that :)

3. You need some sort of sliding window that can gracefully deal with when stuff can't go back too far. I generally just keep the last few seconds of states - if someones ping is more than a second nothing is going to be great anyway. I think clients are fine to only keep the most recent state.

Also very interesting is the GDC talk by the halo reach network programmer: http://www.gdcvault.com/play/1014345/I-Shot-You-First-Networking
The section on state/lag diagrams was particularly enlightening to me, I've tried to draw similar things for game functions before but didn't quite do it right. It's at about the 25th minute.

Good luck!

#4 hplus0603   Moderators   -  Reputation: 4971

Like
0Likes
Like

Posted 24 August 2011 - 04:06 PM

The section on state/lag diagrams was particularly enlightening to me, I've tried to draw similar things for game functions before but didn't quite do it right. It's at about the 25th minute.


Do you mean the sequence diagrams with vertical actor timelines and diagonal messaging arrows? Those are very common in networking papers and design. There's a pretty good tool for generating them online, too: http://www.websequencediagrams.com/ (although this tool doesn't do diagonal crossing arrows, which are often useful as well).
enum Bool { True, False, FileNotFound };

#5 saluk64007   Members   -  Reputation: 156

Like
0Likes
Like

Posted 24 August 2011 - 04:36 PM


The section on state/lag diagrams was particularly enlightening to me, I've tried to draw similar things for game functions before but didn't quite do it right. It's at about the 25th minute.


Do you mean the sequence diagrams with vertical actor timelines and diagonal messaging arrows? Those are very common in networking papers and design. There's a pretty good tool for generating them online, too: http://www.websequencediagrams.com/ (although this tool doesn't do diagonal crossing arrows, which are often useful as well).


Yeah, sequence diagrams with diagonal messaging arrows. Never ran into those before, or if I had they didn't click. Thanks for the link!

#6 Arjan B   Members   -  Reputation: 582

Like
0Likes
Like

Posted 25 August 2011 - 08:29 AM

Thanks for the replies everyone!
I might have read over it, but after skimming through the articles about Quake, Unreal, Source and Tribes, I couldn't really find much about how these timestamps are handled.

1. You shouldn't need to syncronize clocks. The host will probably need to timestamp its gamestate, the client can use the latest received timestamp when buffering inputs to send - i.e., I pressed the "up" key when my gamestate was 1001.


Is there no need to make sure that the timestamp 1001 represents about the same point in time for all players? If for all players the counters start at 0 and increase at the same rate, but one player's game starts 0.3s later, this player will be behind on things 0.3s for the rest of the game right?

2. Bullets are hard. You need to balance "My shot was obviously lined up, so he should take damage" with "theres no way that guy could have hit me". And then of course the host has to be authoritative on the bullet or clients will send fake "I hit this guy" messages. If your states are pretty well in sync, make sure that the shooter tells the server: A) where he thought he was when he fired, and B) what state he thought the other players were at when he fired. If you are handling bullets as physical objects, you should then be able to place it at the right place and going the right direction at the right time so that it makes sense to all players. If it's not a physical object, you can do hit detection on the server side and arbitrate damage as well. I'm sure you will still have fun with this one even if you do all that :)


I will probably have both. No physical object for a sniper, but I'll send a rocket flying with a rocket launcher :). My idea was to just have a player send a message "I pressed the button for firing a shot at this point in time" and the host will be the only one to decide whether it was a hit.

3. You need some sort of sliding window that can gracefully deal with when stuff can't go back too far. I generally just keep the last few seconds of states - if someones ping is more than a second nothing is going to be great anyway. I think clients are fine to only keep the most recent state.


Makes sense to me, I'll go with that too ^^.

Also very interesting is the GDC talk by the halo reach network programmer: http://www.gdcvault....irst-Networking
The section on state/lag diagrams was particularly enlightening to me, I've tried to draw similar things for game functions before but didn't quite do it right. It's at about the 25th minute.


I've watched the first 15 minutes and it seems really interesting. Always loved the Halo games too. I'm sure to watch the rest sometime later this week.

#7 hplus0603   Moderators   -  Reputation: 4971

Like
0Likes
Like

Posted 25 August 2011 - 11:36 AM

Is there no need to make sure that the timestamp 1001 represents about the same point in time for all players? If for all players the counters start at 0 and increase at the same rate, but one player's game starts 0.3s later, this player will be behind on things 0.3s for the rest of the game right?


Each message from the server will have a time stamp. You know that the server's time stamp at the time you receive that message is at or beyond the time stamp in that message.
Your messages should be time stamped as well (and you should relate current time to estimated server timestamp). This is easiest done by mesuring round-trip ping, dividing by two, and adding that to the server timestamp value.
You can use some additional fudge factor, some anti-jitter value, and some slowly adjusting drift factor if you believe that the server's physical clock will advance at a rate different than yours, too. Exactly how you do this depends on your simulation specifics.

Time management has been pretty well researched in the distributed simulation community. A couple of papers that might help:
Lamport: Time, Clocks, and the Ordering of Events in a Distributed System
Fujimoto: Time Management in the High Level Architecture
enum Bool { True, False, FileNotFound };




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