# Network interpolation wont work for local player

im currently developing a little duengon crawler. It should have lan multiplayer and it works great but i think im sending to much packets. Should i send packets over network, when a player moves in delta time? But thats not my question.... Sometimes it lags when more than 2 players are online. So i thought interpolation would be a great idea. But im not sure if i did that right, because it isnt much more fluently when the player moves :/ Heres what i did :

    positionFromInput.set(posX, posY);

differenzX = positionFromInput.x-position.x;
differenzY = positionFromInput.y-position.y;

position.x += differenzX/10;
position.y += differenzY/10;


I thought this would be right ... but it wont work what i did i missed ?

>>>UPDATE<<<

I think it only wont work for the local player because , if theres another player, his position is sended to the host, right after that the other player is drawn correctly with interpolation...

Heres how i move my local player :

public void update(){

state = 0;

if(Gdx.input.isKeyPressed(Keys.A) && moveDirections[0]){
position.x -= Gdx.graphics.getDeltaTime() * 200f;

state = 1;

}
if(Gdx.input.isKeyPressed(Keys.D) && moveDirections[1]){
position.x += Gdx.graphics.getDeltaTime() * 200f;

state = 2;
//System.out.println(currentState);
}
if(Gdx.input.isKeyPressed(Keys.W) && moveDirections[2]){
position.y += Gdx.graphics.getDeltaTime() * 200f;

state = 3;
//System.out.println(currentState);
}
if(Gdx.input.isKeyPressed(Keys.S) && moveDirections[3]){
position.y -= Gdx.graphics.getDeltaTime() * 200f;

state = 4;

}

}


This is being called in an Launcher, which is called in the render method.

Class Launcher{

.
.
.

public void update(){

gameScreen.player.update();

// other stuff like updating packets
.
.
.

}

.
.
.


}

And this is called in the render thread :

@Override
public void render(float delta) {

.
.
.

launcher.update();

.
.
.


}

Thats not all, i also need to draw my player :

public void draw( final float posX, final float posY,  OrthographicCamera camera){

interpolate(posX, posY);

camera.position.set(position.x/Box2dVars.UNIT,position.y/Box2dVars.UNIT,0);
camera.update();

batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(currentFrame, position.x/Box2dVars.UNIT, position.y/Box2dVars.UNIT, playerWidth/Box2dVars.UNIT, playerHeight/Box2dVars.UNIT);
batch.end();

}


The interpolate() is just the interpolation....

private void interpolate(float posX, float posY){

interpolatePosition.set(posX, posY);

differenzX = interpolatePosition.x-position.x;
differenzY = interpolatePosition.y-position.y;

position.x += differenzX/10;
position.y += differenzY/10;

}


To draw the player it is also gonna called in the render thread :

@Override
public void render(float delta) {

.
.
.

launcher.update();

.
.
.

player.draw(launcher.getPlayerX(),launcher.getPlayerY());

.
.
.

}

• "lag" is with one "g" :) – Almo Apr 27 '16 at 13:15
• >.< ohh im sorry, edited it now – genaray Apr 27 '16 at 13:28
• Hahah not a big deal! :) – Almo Apr 27 '16 at 13:29
• That looks conceptually correct. Is it possible for you to post more code to give us a better idea of what is going on? – user3730788 Apr 27 '16 at 13:35
• Sure :) Also need to update this post, just saw that it only wont work for the local host player... If theres another player, his position is sended to the host, right after that the other player is drawn correctly with interpolation... – genaray Apr 27 '16 at 13:55

It looks like you are interpolating your own player, this is not what you want to do. At this point it is not interpolation even, but extrapolation, that is we are guessing where another player went based on their previous path.

Interpolation can be though of as increasing resolution of movement in this case, but please reference better sources than myself.

Consider the following, a player moves 20 units from point A to point B. With no interpolation the player is at A then in time t the player is at B. Interpolation is adding points between A and B. Usually this is done as a function of time to smooth movement. Linear interpolation is of the form f(t) = mt + b, where f(t) is a line between points A and B such that at A + f(0) = A, and A + f(T) = B.

Now, what it appears we are trying to do is say that we have not received a player position recently but the player WAS moving in this direction, let us assume they will continue to do so. You have chosen to extrapolate or predict the players position in a linear manner with respect to their last two positions. The pseudo-code might look something like this...

PositionUpdateFromNetwork:
newSlope = (B.y - lp.y) / (B.x - lp.x)
lp = B
lt = now

Update:
networkedPlayer.position = lp + newSlope * (now - lt)


Note, this could still cause minor extrapolation because Update and PositionUpdateFromNetwork will not be computed at the exact same time, however note as now approaches lt, their value approaches 0 which means the networked players position will approach lp.

I would recommend not extrapolating for a dungeon crawler, but it is of course up to you.

A side note also, if you are experiencing latency problems with only two players you may wish to analyze your networking situation and attempt to make increase efficiency.

• Wow thanks for that very well researched answer :D ! So i did everythink right i guess.... Yeah im using kryonet for sending packets to server and the clients, and i noticed that when i send packets from the client to the server (only movement updates) it lags like hell ... And i dont know why it does :c i think im going to ask in the official kryonet forum. Thanks mate :) – genaray Apr 27 '16 at 15:50