five-on-it / packages/net-client/src/predicted
packages/net-client/src/predicted
Remote vehicles and people drawn at the local time where they may touch what the player controls.
The player's car is predicted: it is drawn at the present, ahead of the server by the inputs in flight. Every other entity is interpolated between snapshots, a hundred milliseconds behind the newest one, which is itself a trip across the network old. Near the player that lag shows: a chaser closing at 100 km/h is drawn six metres behind the twin the prediction collides with, so it shoves the player's car across a visible gap, and a car rammed from behind is drawn inside the rammer. A remote vehicle whose twin is simulated in full (the Mirror decides it may touch the controlled entity before the next snapshot, Mirror.predicts) is drawn where its twin stands instead, at the same moment as the player's car (Mirror.presentPose), the way racing and car-combat games extrapolate the cars around the player: the picture, the local prediction and the server agree on where the bodies meet. So is a person on foot the player's car may hit: drawn where the prediction has it, the hit shows on the frame the car reaches it, the body thrown from the bumper, instead of a hundred milliseconds and a network trip later with the car already through where it stood.
A vehicle that comes near is blended from its interpolated pose to its predicted one, and back once it is no longer near, so it never jumps between the two timelines. The two poses are the same vehicle a timeline's gap apart (the render delay and the inputs in flight: a metre or two of a car's motion), and a blend of a fixed length adds that gap over its length to the car's drawn motion: a quarter of a second over 120 ms of motion drew every car coming near at half again its pace for that quarter of a second, a dash. So the blend is bounded to the vehicle's pace, exactly as the remote buffer draws a guess away: it takes blendSeconds, PREDICTED_BLEND_SECONDS at the least and the gap at a third of the vehicle's speed (BLEND_PACE_SHARE, BLEND_PACE_FLOOR at the least) when that is longer, the gap and the speed measured every frame (PredictedRemotes.apply), so a vehicle accelerating or braking stays within the bound too. It is a blend in space, the drawn pose moved from the one timeline's to the other's, with its length set by the gap; a blend in time (the vehicle's drawn moment advancing from now − delay to now at a bounded rate) would need the twin's trajectory over the inputs in flight, which the replay makes anew at every snapshot and keeps nowhere, and the straight way between two poses of the same vehicle a tenth of a second apart cuts a corner by centimetres. The mirror puts a vehicle on the predicted timeline from as far as this blend needs (Mirror.predicts), so the blend is done before the two can touch.
Each snapshot resets the twins to the server's word and replays; the jump that makes in a predicted twin (its coasting guess against what its driver did) is kept as a decaying offset, as the player's own correction is (SmoothingOffset), and read by the probes by its size (PredictedRemotes.corrected, PredictedRemotes.correcting).