5
\$\begingroup\$

I've implemented client side interpolation, where a specified delay is put on each client. This allows them to interpolate between positions and rotations. Unfortunately, this means every thing else must be delayed, otherwise events ( like a particle effect on a collision ) will happen ahead of time( according to the interpolated data. )

Should I delay everything along with the interpolated data, or do I have the wrong idea about client side interpolation? I haven't seen a single mention of this problem anywhere, which makes me think I'm missing something.

\$\endgroup\$
  • \$\begingroup\$ Try it out! Don't delay RPCs yet, but design your system to be able to buffer them at a later point if you notice visual artifacts with the current implementation. Don't forget about sound effects. I would imagine that delay on sound effects is more noticeable than delay on visual effects. \$\endgroup\$ – mucaho May 19 '15 at 1:48
  • \$\begingroup\$ Any reason why you are not using client-side prediction instead of adding delays? \$\endgroup\$ – Samaursa Jan 26 '18 at 3:43
1
\$\begingroup\$

The easiest way to implement interpolation correctly is by using fixed time steps. Basically, if you know you're going to get a new position about 10 times a second, you can interpolate from the last position to the current one in the time it takes to get a new position (.1 seconds).

In reality, there are things like jitter that make your job harder so packets won't always arrive .1 seconds apart if they're sent .1 seconds apart. This problem can be solved with some buffering. Instead of immediately accepting a position as the current position when you receive it, wait until the next expected sync frame to recognize it.

I.e.

Vector2 LastPos;
Vector2 CurrentPos;
Vector2 BufferPos

//When data is received, store it in the buffer
void OnReceiveData (byte[] RawData)
{
    BufferPos = DeserializationMagic (RawData);
}

//Runs every .1 seconds or however frequent this character gets synced
void FixedUpdate ()
{
    LastPos = CurrentPos;
    CurrentPos = BufferPos;
    ElapsedTime = 0;
    //Send out your position to everyone (except yourself)
    Networking.RPC (transform.position);
}

//Used for smooth interpolation
float ElapsedTime;

//Interpolate position every frame based on time since last position was set
void Update ()
{
    ElapsedTime += Time.deltaTime;
    //Lerps by a factor of 10 since interpolation needs to happen within .1 seconds
    transform.position = Vector3.Lerp (LastPos, CurrentPos, ElapsedTime * 10);
}

There are a bunch of things you can do with time stamps and whatnot for staggered syncing, but at 10 syncs per second, any advantages you get without an expected sync frame probably won't get noticed. Plus, this is the most straightforward and simple way to get smooth interpolation in my opinion.

I don't recommend using RPCs to sync objects though, since the RPC most likely is reliable. Reliable protocols involve sending an ACK packet which means another 20-40 bytes for the packet header. The sender could also resend the original packet if an ACK was not received in time.

Syncing unreliably should be fine since if 1 or 2 packets go missing, the next received packet will fill in the gap.

\$\endgroup\$
  • \$\begingroup\$ This has nothing to do with my question. I know how to interpolate between buffered positions. I'm wondering if this then requires me to delay every RPC and buffer every bit of replicated data so that things don't happen at the wrong time. \$\endgroup\$ – Ben May 16 '15 at 5:02
  • \$\begingroup\$ Look at the example code. There is a maximum delay of .1 seconds exclusive if you recognize the data every .1 seconds, since OnReceiveData can happen at any time. \$\endgroup\$ – JPtheK9 May 16 '15 at 15:03
  • \$\begingroup\$ According to this article: ncbi.nlm.nih.gov/pmc/articles/PMC2871325, player response time peaks around 200 ms. They'll barely notice the 100ms delay, assuming the sync lags 100ms seconds every time (which is highly unlikely). \$\endgroup\$ – JPtheK9 May 16 '15 at 15:14
  • \$\begingroup\$ Plus, if you're not using an authoritative server so there's no reason why latency would be a particularly big deal. Simulate movement and whatnot locally so players get near-instant responses. Everyone else doesn't really matter. \$\endgroup\$ – JPtheK9 May 16 '15 at 15:17
  • \$\begingroup\$ What about explosions and other graphical effects that need to line up with the object positions? I'm not worried so much about delay in input, but about things lining up correctly. I can't delay part of the game, but not the other. \$\endgroup\$ – Ben May 16 '15 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.