Times, trials, and turbulence.
Continued adventures in networking
I think I’m finally at the point where I can call the movement prediction — that’s the logic to perform both ‘guessing’ of where players will be based on old data packets, and the correction logic when prediction errors occur — as being in working order. I haven’t tested it much under high-latency situations, so more fine-tuning will definitely be needed in the future, but it’s at the point where remote players generally appear to move around smoothly and without visible delay.
How does it work? The first half is in performing good estimates of where a player will be after a certain amount of time. Player movement information is sent at a default rate of 4 times per-second. This player movement data packet contains the player’s location, velocity, rotation, and the keys that the player was pressing at the time. From this, once the packet arrives, a decent estimate of how old the contained data is is performed (for now, simply adding client1-server and client2-server latency together). Given a good guess at how old the data is, the remote player’s position/velocity/etc is extrapolated using the regular local player updating logic to where that player should be.
The next step is applying smooth corrections. Usually players will move in pretty predictable ways (eg. in a straight line down a long corridor), so this isn’t often a problem, but in complicated gun fights or when pulling off tight dodges — especially with players that have higher latencies — estimates can quickly diverge from what is ‘expected’. Typically the error isn’t too large, so the real problem is just to move the player from his previously estimated spot (now incorrect) over to the newly-received spot (which is correct) without the user behind the monitor noticing the discrepancy. In previous projects I would just apply linear interpolation between the current-position and the newest-position, which technically worked, but looked pretty cheesy (and obvious) to anyone looking at it. I instead opted for a cubic spline, which is composed of a start point, an end point, and a control point. This creates a smooth curve whose direction is influenced by the given control point. By using a start point of the old position, an end point of the newly-received position, and a control point of where the player would be in the future if the new position didn’t arrive, it creates the illusion of the player continuing to move in the same direction, but smoothing deviating to the player’s true position in a non-obvious manner.
This is the next area I’ve been working on, which is also the last stepping stone before Skirmish is essentially playable as a game, rather than just a neat little demo. 🙂
Props are the most generic object in the game world. Crates, desks, chairs, rockets, firearms, grenades, and shrapnel are all props in Skirmish. A prop could be defined as a “game object that is physically interactable and simulated. Most of these props need to be synchronized such that they behave the same on every player’s computer, which is the crux of the problem.
The current development item is to create a manager which will automatically track the state of the simulation of the players, and send out network messages to update props as appropriate, such as when a player picks something up, throws it away, uses it, or, say, steps on a mine. Doh!
I’ll be talking about this in more detail once I have it implemented and in proper working order. So, here’s to looking forward to smashing some crates together. 🙂