🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Interpolation problem in racing game

Started by
4 comments, last by raz0r007 5 years, 2 months ago

Hi,

I'm developing a racing multiplayer realtime game in C++ with cocos2d-x and box2d. Also, i'm using Nakama for server-logic. The problem that i've is i'm seeing the opponent's car lagged despite of both clients and server are in localhost. I'm sure that the problem is mine, i mean, i'm not hiding correctly the lag in each client.

This is what i'm doing:

  • The game is working with 60 FPS (1/60 updates).
  • ticks to the server are every 0.05 seg.
  • I'm sending opponent's car updates every 1/10 (0.1) seconds to the server (x, y, angle).

Also, i'm using interpolation method for predictions and for "hide" the lag:


void Interpolator::update(float dt)
{
    float difference = _remoteValue - _localValue;
    
    if (difference <= _threshold)
        _localValue = _remoteValue;
    else
    {
        float k = dt * _interpolation_constant;
        
        if (k > 1.f)
            k = 1.f;
        
        _localValue += difference * k;
    }
}

(In Game::update i'm calling Inteporlator::update and after that i'm setting setPosition(localValue) with the localValue updated).

_localValue is the current position of the opponent's car in my client. And _remoteValue is the last position that i received of the opponent's car. _threshould is a constant (0.1f). And _interpolation_constant is a constant that could be [1....60]. It means how many time i will delay for interpolate from position A (localValue) to position B (remoteValue).

So, what's my problem? Currently, i think i have two “extremes”:

Test 1) If i use _interpolation_constant = 1.0f
Opponent’s car works fluid, but with lag. For example, if both cars are accelerating at the same velocity (same position Y in both cars), in my iPhone i see opponent’s car behind of my car, despite of both cars are in the same Y position. That i mean with “lag”. But opponent’s car works fluid. It seems that it hasn’t lag, but it have lag.

It’s fluid because i’m dividing difference in 60 parts (k = 1/60). So, because of i’ve a lot of “parts”, each setPosition is small. I mean, small jumps.

Why i see the opponent’s car with lag? because each 1/10 updates i’m delaying 1 second until remoteValue = localValue. Is too much 1 second. So, my car is in the “present” and the opponent’s car is in the “past”.

 

Test 2) If i use _interpolation_constant = 10.0f
Opponent’s car works without lag, but not fluid. For example, if both cars are accelerating at the same velocity (same position Y in both cars), in my iPhone i see both cars in the same position Y, that’s good. But opponent’s car isn’t fluid.

It’s NOT fluid because i’m dividing difference in 6 parts: k = 1/60 * 10 . So, i’ve few parts. Each setPosition is more big. I mean, big jumps.

Why i see the opponent’s car without lag? because each 1/10 updates i’m delaying 0,1 seconds until remoteValue = localValue. Is the same time that i receives updates.

 

The question is, how to solve this problem? I can't make it work properly.

P.S.: Box2d / physics logic is in each client (i mean, in my car). And about the opponent's car: for move it i'm using only setPosition, without physics, trying to make it work with interpolation method.

 

Advertisement

Help?

@hplus0603

You're trying to solve a problem that fundamentally has no solution. You can't avoid latency. Even if you're on a LAN, because you send a value to the server every six frames, and send a value from the server every three frames, your oldest update frame will be 9 frames "behind" time, plus whatever transmission latencies are.

You can turn up the update rate -- send updates every frame, both to server, and from server. This adds one frame of latency each way, plus transmission time.

Then, you will still have some amount of "competitor is behind" problem. For run-and-gun games, that can be solved by extrapolation, and using some form of smoothed extrapolation to hide jitter (see for example the EPIC library)

Another option is to use a "driver AI" to forward extrapolate what the competitor "would have done" from the time you got an update, to the time you display. Then, when you get a new update, update the previous conditions, and re-run the AI to step it forward to "current time."

None of these options are perfect, because fundamentally, there is latency between player A making a decision, and player B seeing the result of that decision.

 

enum Bool { True, False, FileNotFound };

@hplus0603 thanks for reply. I know that i can't avoid the latency. But i'm trying to "make seem" that i don't have latency. Methods like interpolation/extrapolation makes it, i think.

I will read your example of extrapolation. But, summarizing, how can i solve "opponent is behind" problem? I mean, what's the problem in my code extraction? The problem is that i'm using interpolation instead of extrapolation? To be honest, i'm trying to understand the difference between interpolation and extrapolation.

What i'm doing is: 

  • Opponent's car is in position A and my client received a new position for the opponent's car, called position B.
  • Then, in the client, i'm moving opponent's car from point A to point B in small steps, for avoid the "lag", because if i jump from point A to point B it will not be fluid. I mean, it will have lag.

That's what i'm doing. Why have I "opponent is behind" problem? Because due to i'm jump in small steps instead of jump in only 1 step, i'm delaying...

According to posts in internet, difference between interpolation and extrapolation is :

  • Interpolation let's us approximate something that already happened (we know two points A and B. And we can interpolate from position A to position B).
  • Extrapolation means that we try to predict something, knowing how it behaved in the past.

My question is: why (according to you) extrapolation is better than interpolation in racing games? How can i predict the position of the opponent's car? It's impossible. I could generate a lot of errors. For example: i could move the car foward despite of my opponent has turned to left....

This topic is closed to new replies.

Advertisement