Sync the server position

Started by zammbi, September 06, 2008, 05:12:04 PM

Previous topic - Next topic

zammbi

I'm a totally stuck on the maths trying to sync the movement on the server with the client. Before this I had it so the client sync with the server but that caused annoying warp backs, so I'm trying to make it so the server syncs to the client.
Hopefully I'm too confusing trying to explain this.

The server holds the current client position(CC), current server position (CS), old client position(OC).
The server on every cycle sync as much as it can to the client.

This is done by creating a guess position(G) which the CS goes towards that direction to N (The new position).
G is worked out by the angle of OC and CC, then translate CC with this new angle.
N is worked out by the angle of CS and G, then translate CS with this new angle.

This is my current code but doesn't work as expected, just moves in one direction. Hopefully someone understands this and able to tell me whats wrong.


float differenceAngle = oldrotation - rotation; //has the player turned since last cycle.

final Object3D guessPos = new Object3D(0), charObj = new Object3D(0), newPos = new Object3D(0);

guessPos.translate(clientX, y, clientZ);
guessPos.rotateY(calcAngle(new SimpleVector(oldClientX,y,oldClientZ),new SimpleVector(clientX,y,clientZ)) + differenceAngle);

charObj.translate(x, y, z);
charObj.rotateY(rotation);

final SimpleVector charPos = charObj.getTranslation();

SimpleVector a = guessPos.getZAxis();
a.scalarMul(xSpeed);

newPos.translate(x, y, z);
newPos.rotateY(calcAngle(new SimpleVector(charPos.x,charPos.y,charPos.z),new SimpleVector(a.x,a.y,a.z)));

clientX = a.x;
clientZ = a.y;
clientRotation = a.z;

a = newPos.getZAxis();
a.scalarMul(xSpeed);

               a = m.getWorld().checkCollisionEllipsoid(charPos, a, Zone.ELLIPSOID_RADIUS, 2);

charObj.translate(a);
a = charObj.getTranslation();

x = a.x;
y = a.y;
z = a.z;

oldClientX = clientX;
oldClientZ = clientZ;
oldClientRotation = clientRotation;
oldrotation = rotation;



EgonOlsen


zammbi

Ah sorry, its the method you said in another post.

public static float calcAngle(SimpleVector s1, SimpleVector s2) {
SimpleVector s1n = s1.normalize();
SimpleVector s2n = s2.normalize();

float pa=s1n.x*s2n.x+s1n.y*s2n.y+s1n.z*s2n.z;

// Inaccuracies may cause NaN...fix this:
if (pa<-1) {
pa=-1;
}
if (pa>1) {
pa=1;
}
pa=(float) Math.acos(pa);
return pa;
}


EgonOlsen

I'm not sure if this is part of your problem, but this method returns unsigned angles, because the calculations produce the same result for (s1,s2) as they do for (s2,s1). If you want to interpolate a rotation, i suggest to do this directly on the angle or by interpolating the resulting matrices. I'm still having problems to understand your approach and what exactly goes wrong. A picture is always helpful, at least for a visual oriented guy like me.. ;)

zammbi

#4
Hm.. Yea my approach is hard to understand, thats because I don't really know how to do this right  :-\. The server only holds x,y,z and y rotation. It doesn't hold the objects themselves or the matrix. The client sends the x,y to sync.
Let me try draw what I was explaining before:

                 G
                   /
                  / 
                 /   
           CC /     |N
               /      |
              /        |
________/______|
            OP      CS

Horrible pic heh.
At OP both server and client was sync then they go out of sync after that, so the client is at CC and the server is at CS. So I'm trying to get them back into sync or as much as possible. So we guess the next value which is G.
You see CS is going towards G as close as possible to the new position N.
The Y axis gets ignored since the player doesn't change that, only gravity does.
And its really late here, so looks like I'll work with this tomorrow.

EgonOlsen

Shouldn't one of them simply win (client or server) instead of trying to get back in sync somewhere in the future at G? Who guarantees that this will ever happen if they can go further out of sync in the process (which they obviously can or otherwise CC and CS wouldn't differ).

zammbi

I don't understand?
G may not go there but each cycle will get closer and closer. Which in my above code it adds in the turning angle if the player also turned.
It is always guessing the next move even when not out of sync.

zammbi

Finally worked something out.
I changed it a little, so I made it think that the position was just out of sync and not the angle to make it more simple.
Still not great code at least it works  :)

guessPos.translate(clientX, y, clientZ);
guessPos.rotateY(rotation);

SimpleVector a = guessPos.getZAxis();
a.scalarMul(xSpeed);
guessPos.translate(a);

charObj.translate(x, y, z);
charObj.rotateY(rotation);

final SimpleVector charPos = charObj.getTranslation();


a = guessPos.getTranslation();
newPos.translate(x, y, z);
float ang = (float) ((float) Math.atan2(x - a.x, z - a.z) +Math.PI);
newPos.rotateY(ang);

//System.out.println("ang: " + ang + " x: " + x + " a.x:" + a.x + " z: " + z + " a.z: " + a.z);

clientX = a.x;
clientZ = a.z;

a = newPos.getZAxis();
a.scalarMul(xSpeed);

a = MapLocation.get().checkCollision(charPos, a);

charObj.translate(a);
a = charObj.getTranslation();

x = a.x;
y = a.y;
z = a.z;


Melssj5

In my unfinished and buggy project FLierMatch, the server manages the position and direccion of a spaceship and for each movement it transfer it to each client and each client upgrades the position and direction of the ship inside the client game.

Check it, maybe is what you need.
Nada por ahora

EgonOlsen

In "nameless bomberman clone", each client is responsible for its own objects' movement and collision, it transfers this to the server, the server does a rough plausibility check and transfer the data to all other clients, which themselves use interpolation to smooth the movement of those remote objects. This somehow violates the "never trust the client-blahblah", but it works reasonable well for that kind of game.

zammbi

#10
Quote from: Melssj5 on September 08, 2008, 07:38:16 PM
In my unfinished and buggy project FLierMatch, the server manages the position and direccion of a spaceship and for each movement it transfer it to each client and each client upgrades the position and direction of the ship inside the client game.
Thats what I did first. But caused a lot of warp back.
The server currently will still send the position if its totally out of sync. What I have now does what I want, though I will make it a little smarter later.