Advertisement

How to add non-jittery speed to an interpolation lerp?

Started by October 30, 2018 10:00 AM
2 comments, last by WombatTurkey 6 years ago

Stumbled upon this thread: 

@Simmie's answer and others helped immensely. I was running into the same issue as OP in that thread, and Simmie's solution worked great. 

How my server is setup: (I trust the client too much, but I want to get everything working before diving into more advanced stuff). 

- Server tick rate is 10 times per second

- Client side network tick rate (sends positional data to server), is 10 times per second

 

Interpolation code (Godot)


var realPosition = Vector2()
var lastRealPosition = Vector2()
var t = 0.00
func _process(delta):
	t += delta
	t = clamp(t, 0, 1)
	$monster.global_position = lastRealPosition.linear_interpolate(realPosition, t)

When a new message is received (server, using crystal-lang)


t = 0 # Resets on each   positional update
lastRealPosition = $monster.global_position
realPosition = incoming_position # (position from server)

 

This works great so far. The monster sprite transitions itself towards the end position very smoothly!

However, there is one problem! It moves very, very slow and doesn't interpolate fast enough.
7ea91fc60576d699c453815a1c9b6fd6.gif

Is there a way to increase this so it interpolates faster? I tried doing t+= delta * 10.00, but then the lerping tries to "catch up to the player".

What could be causing that? It's hard to see, but the $monster sprite catches up to the end position, then stops.. then continues again. It's only buttery smooth if I do t += delta. 

 

Does t go from 0 to 1 over the duration of a single tick? If not, it probably should. When that is the case though, try to imagine what happens if you don't get a new update in time: your position doesn't get updated and the movement stops until the next update is in. There are two ways to remedy this, each with their own pros and cons:

  1. Buffer the updates and introduce an artificial delay (known as a dejitter buffer) by interpolating between older updates. This way it's more likely you'll always have an update to interpolate with, but comes with the cost of extra delay.
  2. If there's no new update in yet, extrapolate the position based on the last know velocity (or something similar) so that movement doesn't grind to a halt. This obviously comes with the drawback that your prediction can and will be wrong sometimes, resulting in overshooting the position when the player stops or going on in the wrong direction until the new update is in.

Whichever one is better suited for you depends on the type of game you're making.

Advertisement
On 10/30/2018 at 4:46 AM, Mussi said:

Buffer the updates and introduce an artificial delay (known as a dejitter buffer) by interpolating between older updates. This way it's more likely you'll always have an update to interpolate with, but comes with the cost of extra delay.

This has been the hardest thing I've ever experienced while making the game. I've been stuck on this issue for nearly 3 weeks (not even exaggerating) before even making this topic. I finally got something working over the network:

https://i.gyazo.com/a6249d5deca325e0d1d29bf2dda936a2.mp4

The red boxes are the  server positional data, and the player (face icon) is  transitioning through them (12hz tickrate, 50-60ms RTT).  I finally got it to be smooth.  I was moving around for 2 minutes in awe spamming WASD and noticed barely no jitter (unless lag, or this $3/year VPS has a hiccup). Will worry about that at another day, I really need a break from this dilemma and work on something else.

 It's a great step forward for me.  Am very excited and appreciative that this forum exists, don't believe I would be where I am today without it.

Thank you so much.

This topic is closed to new replies.

Advertisement