geckosio / snapshot-interpolation

A Snapshot Interpolation library for Real-Time Multiplayer Games.
BSD 3-Clause "New" or "Revised" License
269 stars 23 forks source link

Deterministic physics sync with clients - rubberbanding issue #17

Open finkton1 opened 2 years ago

finkton1 commented 2 years ago

This could be just an implimentation issue on my end.

My setup I am tryign to achieve is syncing positions to the client (x, y) with snapshot interpolation. My server is actually running matter.js physics in headless mode, simulating physics on server side.

I send position updates to the clients 15 frames per second. With snapshot interpolation.

Then on client side i calculate the interpolation.

All seems to be good, but I run into a strange behavior.... every once in a while the sprites that are moving based on position updates to the server seem to act strangely. They jerk around and sometime rubberband, then it smooths out again.

Would anyone know what approach I could do to fix that?

I am using Phaser 3 as client, moving the positions within the update loop (60fps). The server sends position updates at 15fps by simulating physics on server side (matter.js).

public update(time, delta): void {

    const snapshot = this.SI.calcInterpolation('x y', 'balls') // interpolated

 if (snapshot) {
    const { state } = snapshot
    const { percentage } = snapshot
    state.forEach(s => {
      const { x, y, entityId } = s
        const ballId = entityId as number
        //get the specific instance of the ball in Phaser
        const ball = this.playerBallGroup.getBallById(ballId);

        let differenceX = x as number - ball.x;
        let differenceY = y as number - ball.y;

        ball.x += differenceX * delta * 0.1;
        ball.y += differenceY * delta * 0.1;

    })
    }
}

Any help is appreciated - been struggling with this for quite some time.

yandeu commented 2 years ago

I guess on high cpu load, delta could be higher than expected and causing the issue?

Is delta in seconds? Can you try to use a fix value for delta, like 1/60?


Or is the library giving you odd values? Can you please check it to make sure?

finkton1 commented 2 years ago

I guess on high cpu load, delta could be higher than expected and causing the issue?

Is delta in seconds? Can you try to use a fix value for delta, like 1/60?

Or is the library giving you odd values? Can you please check it to make sure?

It looks like this is the issue.

I am comparing in my update loop (fixed timestep 16.66) the difference between the rendered object x and y against the recieved snapshot x and y.

I see some difference values not lining up with what I expect.

For example, I send an object traveling down Y axis, you would expect differences to be positive. I log to console and see most of these values are indeed positive. However, I see some values as negative.

It seems like the rendered ball position is ahead of some snapshots.

Is there a way I could throw out snapshots if they are too old?

finkton1 commented 2 years ago

@yandeu I did some further testing and can see some snapshots that come in seem older. Causing the objects to jitter.

ie: snapshot on tick 49 has a Y value of 472, the next snapshot for the same object on tick 50 would be 460. The difference would be 12px, causing jitter.

yandeu commented 2 years ago

You could drop all snapshots that are older than the previous shapshot. Get the time from a snapshot, compare, and call (or not) SI.snapshot.add(snapshot)

finkton1 commented 2 years ago

You could drop all snapshots that are older than the previous shapshot. Get the time from a snapshot, compare, and call (or not) SI.snapshot.add(snapshot)

I have implemented that - seemed to help a bit. Thanks!

However, I still seem to see artifacts of the object teleporting/ jerking (ie taking a step back in position for a split second, and then re appearing back into the position it should) - seems to be related to high latency and/ or packet loss; in which the snapshot queue runs out of snapshots to interpolate against for a split second?

I've tried to increase interpolation buffer, but it does not seem to help much.

Does the snapshot interpolation library account for such? Is there any further enhancements you would suggest I do to further smooth this out?

Maeggi commented 2 years ago

I have the same problem with Phaser. Have you already found a Solution?