KryoNet Player Locations

When using KryoNet in a 3D multiplayer game with a big world, do I have to send every Players Location to every Client? even if they aren’t in range for them to see? And how do i manage the connected clients? ArrayList doesn’t work that well throwing ConcurrentModificationExceptions on Disconnect, so How to Store the data?

You want to send to every client all relevant entities. This can be determined in the following ways:

  • An entity is relevant if it’s within X units (hearing distance)
  • An entity is relevant if it’s within the view frustum within a specified distance (or line-of-sight)
  • An entity is relevant if it is flagged as always relevant
  • An entity is relevant if it was relevant for another reason in the pass Y seconds.

When entities connect to my server, the server gives out an ID (as an int for example)… to store entities on the clients I keep it in a Map<ID, Entity>.

Basically the server knows what entities are relevant to each client. When the server receives an entity create/update/death message it makes sure to tell the client when a new entity is created, it’s not relevant, it is relevant, an entity has updated, and an entity has been removed. The server only sends updates to relevant clients, but creates and deaths to all clients.

I hope this helps!

Okay, when I Store Entities in a Map<ID, Entity> how can I add an Entity which is controled by the Server with some AI? If I just give it an ID the next Connection could have the same ID which would cause problems no?

Here’s my ID generation/sync process:

  1. Client generates a LOCAL ID when an entity (like a bullet or grenade or something) is created and sends to server.
  2. Server generates a REMOTE ID which is unique to the server (the server can do nextId++ or something) and the server sends a message to the client “your LOCAL ID should be changed to REMOTE ID so we’re in sync”
  3. Client only sends information now with REMOTE ID given by server

ah so for the IDs you don’t use the ID KryoNet creates (“Connection.getID()”)? You create your own IDs?

I don’t use Kryonet, but I wouldn’t use their ID stuff if I did.

Okay, i’m going to generate my own IDs now. Next Problem: Map<ID, Entity> can’t use an integer as an ID an using an Object which just stores that ID doesn’t support the Function to just call Map.get(new ID(5)); and get the Entity cause the ID object isn’t the same

public void remove(int ID) {
		for (ID id : entities.keySet()) {
			if (id.ID == ID) {
				entities.remove(id);
				break;
			}
		}
	}

trying out this now

You can do Map<Integer, Entity> map = … and map.get(5) will work. map.remove(4) will also work.

Ah, tryed it with just “int” what did not work :smiley: what Kind of Map should i use best? HashMap?

Are you using a game engine? Some come with IntMap which is far better than using Map<Integer, Entity>. I would use HashMap if you don’t have access to something like an IntMap.

No, I’m not using an Engine, i’m just using KryoNet for Network and LWJGL for Graphics. So I’ll stay with HashMaps :smiley:

So the next thing is the Interpolation on Client side, would it work if i send the coordinates (x,y,z) + Rotation and Movement directions (dx,dy,dz) for an ID and for Interpolation i send System.nanoTime(); in a long so the Client knows when the position was exact and can interpolate it with his System.nanoTime();?

I do this for interpolation:

A simple Entity structure: { ping, lastUpdateTime, time, lastPosition, nextPosition, position }

When I get an update for an entity


long currentTime = System.nanoTime();
user.ping = (currentTime - user.lastUpdateTime) * 0.000000001f; // in seconds
user.lastUpdateTime = currentTime;
user.lastPosition.set( user.position );
user.nextPosition.set( UPDATE.newPosition );

Every update call (where dt is seconds since last update)


user.time += dt;
user.position = (user.nextPosition - user.lastPosition) * (user.time / user.ping) + user.lastPosition;

This handles interpolation from previous position to new, and even extrapolation if time passes expected ping (you don’t receive an UPDATE in ping seconds).

You can apply this logic to other things like direction and velocity if necessary.