-
|
|
Peer to Peer, Timers and FixedTimeStep
|
This is a fairly old case that was addressed but I'd like to find a way around this problem more specifically.
Computers run games at barely noticably different speeds according to their timers (if what I've learned is correct). If this is true, if I ran the same game on two different computers at the same time with fixed timestep enabled, they'd eventually desynch and I don't think theres anyway I could prove it without input from a second computer. For a peer to peeer connection I'd assume this to be a problem for something like a racing game.
Is this something that is genreally ignored or is there a way around this? I really can't see a way pass this if fixed timestep guarantees that the update method is to be called 60 times per second (the timers image of a second at least). The only thing I can think of is somehow stalling the faster computer whenever it jumps ahead when connected...
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
Simulations are typically time stepped, meaning that the rules advance by step numbers (not arbitrary time). Peers should exchange their idea of the "current step number" and make sure they don't get out of sync. This may mean temporarily stalling a too fast client by 1/60th of a second now and then. You could make it so that, if one peer keeps stalling many times, it adjusts its relation between "real time" and "step number" down by a fraction, so that he will have a better estimate of the pace of simulation at the other end. Just make sure you don't keep doing mutual adjustments down until the entire game runs in slow motion ;-)
Jon Watte, Direct3D MVP
kW X-port 3ds Max .X exporter
kW Animation source code
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
Another method is, since the two computers will be sending the timer data anyway, have a "master" client, say, client #1. That client will always send its timer data to the other client, and the other client will displays its clock based on that data and forgo its built in clock function.
Much less calculation and both games can run at the native speeds of their computers.
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
I was going over how to perform the advice you two had given me when a very interesting find surfaced!
Originally I had set the TargetElapsedTime to the default value I also tried TimeSpan.FromSeconds(1d/60) to no avail. I'm not sure what, but, something in what JohnWestMinor made me change it to TimeSpan.FromTicks(60000) and from what I see the games runs in synch!? I tried setting it back to make sure and, believe it or not, it went back to its usual tricks when I did. I wasn't just getting lucky.
Erm thanks for the help I guess : D!! But can anyone explain why this works or didn't work? I would've thought that they did the same thing.
Update:
I should probably test more thoroughly before replying. I realized I had a delta value enabled when testing. When I set the delta value to 1 (as more experienced people probably guessed) the game moved at a very fast speed. So, I set the correct value of TargetElaspedTime to TimeSpan.FromTicks(10000000/60) and the game began desynching again. This is all very confusing. I believe I'll go back to try the listed techniques to avoid running the loop more than needed.
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
I only use fixed timestep for testing multiple application on a single computer. (IMO) the speed of a computer has nothing to do or has a little impact to desynch your network play if every PCs has the same state of every network object.
The fastest pc will just do the rendering much smoother e.g. for a racing game if the slowest pc player is on the 10th KM the other pcs should also see the car on 10th KM, But of course the fastest pc will just render the car engine smoke smoothly ;)) but the position and the state of every car should be in sync by applying a method like dead recokning or some other latency hiding techniques.
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
JohnWest, the problem with that approach is that you don't get any data in-between the received packets, and if you simulate at 60 Hz but send network packets at 10 Hz, that's a problem. The other problem is that you will see jitter on the other machines when the network packets get delayed or dropped. It's better to use the local clock, but adjusted based on information you gather (through statistics) from looking at the time on other players.
Jon Watte, Direct3D MVP
kW X-port 3ds Max .X exporter
kW Animation source code
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
Okay I think I've got it. For the host I've set a value for the Hosting "Ticks" which, by my terms, is the number of frames since the connection. For others, I send this value to them and they set it against their own number of frames since the connection. When the game is ahead I gradually pause it from time to time to keep smoothness. When the game is behind I gradually run an extra frame or so to follow suite.
Thanks for the help.
|
|
-
|
|
Re: Peer to Peer, Timers and FixedTimeStep
|
Time is really no different to any other game parameter.
You can think of a game as a giant simulation. When you make a networked game, parallel copies of these simulations are running on each machine. Because things are never exactly in sync (due to latency, packet loss, limited ability to send data from one machine to another, etc), these simulations will gradually diverge. It's like the butterfly effect: a single dropped frame may initially be only a tiny difference, but after another few minutes of gameplay, this will have magnified to the point where the two machines are obviously in a totally different state.
The goal of a good game networking system is to keep all simulations close enough together that the player will never notice any errors.
You can tackle this on many levels. One way would be to synchronize just the most basic input parameters, like time, gamepad button presses, etc, and then rely on each machine to independently repeat the exact same simulation based on those inputs. This can be very efficient (because there are typically not very many inputs) but is extremely fragile (if anything goes even slightly out of sync, it is then impossible to recover).
Another approach is just to let the input parameters get out of sync, and then re-coordinate higher level results such as the position of your player character in the game world. With that approach, it doesn't matter so much if a single frame goes missing, or a button press gets missed, since a later network packet will correct for it and move the player to their correct position regardless.
Choosing the right things to synchronize isn't easy, and tends to be different for each game: you need to find the right balance of objects which will be relatively small to synchronize, and relatively stable in their behaviors (so you can predict how they will move in between packets without too much butterfly-effect chaos getting in the way), while still being comprehensive enough to make the simulation seem consistent to the player.
For some games, time could well be one of the things that needs to be synchronized, but for many it will not be. Bear in mind that network packet send rates are very low (often around 5 to 20 frames per second) compared to game update framerates (typically 60 frames a second, or sometimes 30). This means that once you implement some prediction and smoothing to fill in the gaps between your 5 frames per second network packets, it may not end up making any difference at all if one machine happens to drop a 1/60 second frame during that interval, while another does not.
XNA Framework Developer -
blog - homepage
|
|
|