How to implement variable-step rendering properly?

Started by
11 comments, last by Heelp 7 years, 7 months ago
You can't synchronise real-time games across the network like that anyway (because by the time information arrives at the destination, it's out of date) so any attempt to maintain perfect synchronisation is a failed endeavour. Floating point precision issues should therefore never come into play.

All you need is for it to be close enough, by sending updates frequently and smoothing over any error correction that might need to happen.
Advertisement

To do interpolation instead of extrapolation, when you read the input state, timestamp it in the future by a constant amount (probably one frame's time). Then the current time will be between the previous input state and the most recent state. Or more specifically, if t is between 0.0 and 1.0, you get interpolation, and greater than 1.0 becomes extrapolation.

I want to have the exact amount of floating point multiplications for every PC in order to preserve simulation predictability.

That approach is called lockstep, and only works on fast local networks like between handheld game systems. I have worked on games that used it to run at 30fps in perfect synchronization with no added latency (and therefore no need for any prediction or interpolation), but it is very tricky making sure that everything (including the main random number generator) gets called identically on all systems. And I'm not sure I'd ever trust floating point to come out exactly the same unless you can ensure that both CPUs are exactly the same model. Fixed-point is entirely predictable, though.

But for PC games, and especially over the internet, you'll have to use a packet system to inform players about events, and use prediction while you wait. And when you do receive a packet, setting the position immediately could make things jumpy, so it may be better to interpolate between the old predicted position and new predicted position so it looks smooth even if it's less accurate.

I've never actually done internet multiplayer, but you'll probably need to declare one player to be the boss, who resolves conflicts between events if necessary.

Approach #1: When you shoot at someone, you can check if you hit your target at its visible position on the local machine, and if so, send out a packet to everyone else saying "hey, I just shot Doofus in the arm", and everyone including Doofus will accept that as fact, even if he had actually rounded a corner before the shot was fired.

Approach #2: Send a packet to Doofus saying "hey, I shot you", and if he agrees that it was plausible for him to be shot, he sends out a packet to everyone saying "that guy just shot me". That gives Doofus an opportunity to modify the event, if he was actually past the corner a significant amount of time before the shot was fired, or if he'd done some special move to block the shot.

Approach #3: Send a packet to boss saying "I just shot Doofus", and if boss agrees, then he sends out a packet to everyone.

In the first two approaches, you can end up with conflicts, like if two players believe they picked up the same item. The third approach allows the boss to resolve that before it happens. Alternatively you could do one of the first approaches, but have the boss check for conflicts among all the information he receives and send out corrections to everyone when necessary. But it's also wise to think in terms of what is the most fun. If it doesn't cause any problems, you could just let both players have the item.

Fixed-point is entirely predictable, though.

I made a little research on fixed-point numbers, they seem really cool. I really don't know why the whole world is using floating point when it causes so many different problems.

Approach #3: Send a packet to boss saying "I just shot Doofus", and if boss agrees, then he sends out a packet to everyone.

I will go with this, because it's kind of easier. I will just send game states to the server and then let the server send back the action. For example, if you want to move, you press "W", this way you send "Move Forward" packet to the server and the server returns the coordinates of the movement. Kind of like a pure-client server arch.

This topic is closed to new replies.

Advertisement