Optimizing networking

I created a simple game using jme3 and SpiderMonkey.

I use the server for calculating physics and then inform the client about the position of moving objects.

For now I start a new thread from the server and every 50 to 100 milliseconds it sends a UDP message with the new positions but the client side is choppy.

If I lower this value and send the message more often then there is a delay before the changes take effect.



Is this the maximum performance or is there a better way for synchronization?

Try using physics on the client side as well, it should “interpolate” the movement.

Cheers,

Normen

Or write a interpolation controller (and maybee add prediction?)

Code:
package online.newhorizons.client.interpolation;

import online.newhorizons.client.entity.CEntity;

import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;

public abstract class CInterpolate {
protected Vector3f ipos = new Vector3f();
protected Quaternion irot = new Quaternion();
protected Vector3f ivelocity= new Vector3f();
protected Vector3f iangularv= new Vector3f();
protected CEntity ent = null;

public abstract void update(float timedif);
public abstract void setNewPosition(Vector3f pos);
public abstract void setNewRotation(Quaternion rot);
public abstract void setNewVelocity(Vector3f velo);
public abstract void setNewAngularVelocity(Vector3f vector3f);

public Vector3f getPositionInterpolated(){
	return this.ipos ;
}
public Quaternion getRotationInterpolated(){
	return this.irot;
}
public Vector3f getVelocity(){
	return this.ivelocity;
}
public Vector3f getAngularVelocity(){
	return this.iangularv;
}

public void setObject(CEntity ent) {
	this.ent = ent;
}

protected void apply(){
	this.ent.getVisibleNode().setLocalTranslation(this.ipos);
	this.ent.getVisibleNode().setLocalRotation(this.irot);
}

}

Code:
package online.newhorizons.client.interpolation;

import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;

public class QuadraticInterpolation extends CInterpolate {
private Vector3f newpos = new Vector3f();
private Quaternion newrot = new Quaternion();

@Override
public void setNewPosition(Vector3f pos) {
	newpos = pos;
	if(this.ipos.equals(Vector3f.ZERO)){
		this.ipos = pos;
	}
}

@Override
public void setNewRotation(Quaternion rot) {
	newrot = rot;
	if(this.irot.equals(Quaternion.IDENTITY)){
		this.irot = rot;
	}
}

@Override
public void setNewVelocity(Vector3f velo) {
	//unimportant here
}

@Override
public void update(float timedif) {
	float scale = timedif*10;
	if(scale > 1){
		scale = 1;
	}
	//TODO: we need added velocity and angularv calcs
	ipos.interpolate(newpos,scale);
	irot.slerp(newrot,scale);
	this.apply();
}

@Override
public void setNewAngularVelocity(Vector3f vector3f) {
	//unimportant here
}

}


Not completly optimized, this does a fair job currently in my NewHorizons project

Thank you both for your replies.

EmpirePhoenix could you please explain the code a little?

Is ipos the old position and newpos the position the server tells the client to move the object to?

changeAmnt from interpolate and slerp show how much of the differnce will be covered?

Well the server sets the position every 50 milliseconds in my game, the client then moves the entities slowly (via ipos and irot) to the desired position. ( So actually everything you see is a little behind the data sent from the server.)



This system allows to add a bit more functions, like allow the player to move forward, and predict clientside at least static collisions, to reduce the effect of delayed walking ( else you would have a 50 ms delay between pressing button and starting to move)



You should only use the addnew and the update(and probably modify the apply )

Thanks again:)

I will try both ways and see what fits me more.

I have recently got my project to the point where multiple people can connect and run around inside the environment. The problem I’m having is as follows. If im the player running around and I see other players, they look extremely choppy. I am applying physics on the client side so if the 2 players collide the client recognizes it. I think the problem is because I am handling the other players by grabbing their localtranslation and sending that position over the network to the server. The current player reads those values from the server and just places the other players in that position. I have been reading articles on synchronization of physics and different practices on how to do it.



The main approach I’ve read about is to just send the walk direction instead of the translation and let the player move the other players. I’ve been trying this and I’m not having very much luck. I was wondering what would be a good approach that implements something like this, or how do I write a physics synconization piece. I have seen the examples for what I am guessing was for JGN and JME2, and those principles don’t seem like they would be a good fit to my game.



The code empire posted looks intriguing I am just not sure how I would go about implementing that, or if that is what I really need.



Any help is much appreciated.

Well what the code basically does, it moves/rotates entities to the position/rotation recived from server not instantly, but delayed over a few frames and incrementally, this leads to a smoother feeling.

The effect I’m trying to go for is described here.

http://www.gamasutra.com/view/feature/3230/dead_reckoning_latency_hiding_for_.php


Without some sort of extrapolation algorithm, the single entity state PDU sent at start-up would cause the entity to appear remotely, but the remote entity would be static; it would only move as additional PDUs describing its updated parameters were sent out. Thus, the motion of remote entities would seem choppy; they would stay still until the next PDU was received, and would jump to the location specified in the new PDU. This choppiness can be lessened by decreasing the time between PDUs, but this approach quickly exhausts available network bandwidth in scenarios with large numbers of entities.


That is what I am experiencing. The article goes on to say to use the dead reckoning algorithm (which is physics based).

With dead reckoning, however, after receipt of the first entity state PDU for an entity, each node on the net begins moving the entity by applying the agreed-upon dead reckoning algorithm. As long as the entity continues to move in a predictable fashion, it appears in a consistent, synchronized way on all nodes on the net with no further network traffic required.


Which in the case of my game I am using bullet physics with a PhysicsCharacterNode. So the applied force and direction to move is easily set by using character.setWalkDirection. What also makes this hard to debug is the fact that I need two computers, or even just another person because if I have two clients open on my machine, only one client is actively being updated because the other one doesn't have focus. I have ran a few tests with another person but the walk direction method wasn't working to well. (Still trying to debug it).

If I can't get this method to work I think I might try using your code Empire. How would I go about using it in a test case?

I was looking for a good “recipe” to make a fps multyplayer network and I came into this thread.

Have you reached a goal? Otherwise, can you just share you opinions?

Thanks!

r.

If you’re still having issues, reread Empires posts until it makes sense. He’s right on target. From the other FPS thread someone was nice enough to link this: http://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking



I reread that thing 50+ times until it finally made sense.



We recently got our networked movement smoothed out, even with lag, thanks to these forums and the link I posted above. My suggestion is start with interpolation first and make sure that’s solid before moving on to any of the other concepts. Interpolation will make the biggest impact on the feel of your game. The other concepts listed in the article are more for polish but do make a difference. For examples on interpolation, look at Empires code above or check out the Sync code under /Network. The Sync code interpolates a box from A to B in a reasonably smooth manner. Disable jitter and lag to see how smooth it can be.



Another thing to note, you might only want to interpolate your remote players. Depends on your scenario really. Server should have the ultimate say over where the player is located, but maybe only force the position in the event of cheating. Say a player moves faster then the server expects, force the player back to a known acceptable location.

Spyd said:
I created a simple game using jme3 and SpiderMonkey.
I use the server for calculating physics and then inform the client about the position of moving objects.
For now I start a new thread from the server and every 50 to 100 milliseconds it sends a UDP message with the new positions but the client side is choppy.
If I lower this value and send the message more often then there is a delay before the changes take effect.

Is this the maximum performance or is there a better way for synchronization?


I'm a little confused about the original approach. Why not allow the client to calculate all of this on its own, just as the server is doing. This way you only need to send minor amounts of information to each client to have everything sync up.

projectile example:

projectile is launched at a certain velocity, in a certain direction with a certain weight in predefined gravity. If the server and all clients know the start pos, direction, velocity, etc, etc... the physics model will produce the same results, over the same period of time on the server and all clients.

Sooo... question is:

Why are you updating the clients on a cycled basis with position? Even if the it is complex movement, the above approach still works with minimal updates needed to sync client > server > clients. Use interpolation for any discrepancies when an update is needed to be sent.

EDIT: I just realized you're using spidermonkey. Never used it, no idea how it works... maybe my suggestion doesn't apply in this case. Sorry if that is the case.

yes your suggestion works with spidermonkey

all spidermonkey does is take care of the actual sending / receiving of messages. The actual content of the message is all up to you.

t0neg0d said:
I'm a little confused about the original approach. Why not allow the client to calculate all of this on its own, just as the server is doing. This way you only need to send minor amounts of information to each client to have everything sync up.

MonkeyZone does that in combination with a steady sync of object locations and speed / rotation speed, otherwise you will get drift, no matter how good your syncing is.
1 Like