RevenantX/NetGameExample

What is NetworkGeneral.SeqDiff(...) and Why is it Used for Interpolation?

Lunar2kPS opened this issue · 2 comments

public const int MaxGameSequence = 1024;
public const int HalfMaxGameSequence = MaxGameSequence / 2;
public static int SeqDiff(int a, int b)
{
return Diff(a, b, HalfMaxGameSequence);
}
public static int Diff(int a, int b, int halfMax)
{
return (a - b + halfMax*3) % (halfMax*2) - halfMax;
}

I was trying to understand the RemotePlayer.cs logic for interpolating remote players' positions (since we only get so much data from the network, and we want to smooth out the display of other players' positions over time).

However, I don't understand what NetworkGeneral.SeqDiff(...) is doing, nor why MaxGameSequence = 1024 nor what that variable means.
Would someone be able to explain?

dabbe commented

Short answer: To be able to compare packets and see which is newer (and also account for wrapping around the maximum value).

Longer answer:
Think of it as a subtraction (that fixes a problem described below). Seriously, that's all it is.

When is it used, you might ask. The server sends packets with an incrementing packet id (first packet 1, then packet 2 etc) and the client always only cares about the latest one, and we never want to act on a packet that we've already seen before. Why is that a problem and don't they not come in order? Well, UDP does not guarantee any of these three principes:

a) That packets arrive in order
b) That packets arrive at all
c) That the same packet never sent more than once

If my packet id is larger than the largest I've seen before, it's a new packet and we want to keep it and act on it!

Ok sooo, why don't we simply do newPacket.id - oldPacket.id? Well, what happens if we reach the upper boundaries of the data type that is holding the id? You'd have errors in your subtraction. So packets from the server is sent like this: 1,2,3....1022,1023,1024,1,2,3... As you can see, 1023 actually comes before 3. So our comparison must also work when the packet id number wraps after its max value. Hence the calculation you've posted.

Why not use a larger number? You'd have to ask @RevenantX. One limitation one has to consider is that the intermediate values in the calculation have to be within the boundaries of the data type. (Which is larger than 1024 fwiw)

More specifically regarding the line you linked to in the RemotePlayer file, you want to find out how much time you should be lerping between dataB and dataA, by figuring out how great the difference is between their ids. That information is then multiplied by the time between ticks (between packets being sent from the server). I.e. lerpTime more or less means "how many milliseconds in real time passed between these two ticks?".

Wow.
What an excellent explanation, that helps a lot -- thanks so much for your time! :)