Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deterministic physics sync with clients - rubberbanding issue #17

Open
finkton1 opened this issue Jan 11, 2022 · 6 comments
Open

Deterministic physics sync with clients - rubberbanding issue #17

finkton1 opened this issue Jan 11, 2022 · 6 comments

Comments

@finkton1
Copy link

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.

@finkton1 finkton1 changed the title Jan 11, 2022
@yandeu
Copy link
Member

yandeu commented Jan 12, 2022

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
Copy link
Author

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
Copy link
Author

@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
Copy link
Member

yandeu commented Jan 15, 2022

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
Copy link
Author

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?

@yandeu yandeu transferred this issue from geckosio/geckos.io Jan 19, 2022
@Maeggi
Copy link

Maeggi commented Mar 8, 2022

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants