In player updating, there is an array of players that were added to the client in a previous cycle, that will be used to send their movements in the movement part of player updating. Instead of using an array with player objects (which is fairly expensive when you have alot of players online) you can generate a UUID (Universal Unique Identifier) that will be unique for every player.
Code:
private final UUID uuid = UUID.randomUUID();
I don't know if the player update methods are much different than the ones in pali's server, but I guess graham used pali's methods, so this is applicable on both frameworks, but I'll use pali's methods as an example as I remembered pali doing this really inefficiently.
Current part of the updatePlayer() method in pali:
Code:
str.writeBits(8, p.playerListSize);
int size = p.playerListSize;
p.playerListSize = 0;
for (int i = 0; i < size; i++) {
if (p.playerList[i] == null || !withinDistance(p, p.playerList[i]) || p.playerList[i].didTeleport) {
if (p.playerList[i] != null)
p.playersInList[p.playerList[i].playerId] = 0;
str.writeBits(1, 1);
str.writeBits(2, 3);
} else {
Engine.playerMovement.updatePlayerMovement(p.playerList[i], str);
p.playerList[p.playerListSize++] = p.playerList[i];
}
}
There it calls the array playerList. That list is filled in the next method of player updating, where the server sends the players to the client to be added:
Code:
public void addNewPlayer(Player p, Player p2, Stream str) {
if (p == null || p2 == null || str == null) {
return;
}
int yPos = p2.absY - p.absY;
if (yPos > 15)
yPos += 32;
int xPos = p2.absX - p.absX;
if (xPos > 15)
xPos += 32;
p.playersInList[p2.playerId] = 1;
p.playerList[p.playerListSize++] = p2;
str.writeBits(11, p2.playerId);
str.writeBits(1, 1);
str.writeBits(5, xPos);
str.writeBits(1, 1);
str.writeBits(3, 1);
str.writeBits(5, yPos);
}
You see, an array with player objects is quite expensive as player objects probably cover most of your memory usage. Usage of a list for every player with UUID's would lower this memory usage by alot (especially when you have alot of players online).
Code:
private final Deque<UUID> uuidDeque = new ArrayDeque<UUID>();
Now all you have to do is write a method to retrieve the player object from the UUID whilst looping trough the Deque removing each first element everytime. This is the part you will have to change, I've highlighted what to change, now it is up to you to figure it out (the least you can do ):
Code:
str.writeBits(8, p.playerListSize);
int size = p.playerListSize;
p.playerListSize = 0;
for (int i = 0; i < size; i++) {
if (p.playerList[i] == null || !withinDistance(p, p.playerList[i]) || p.playerList[i].didTeleport) {
if (p.playerList[i] != null)
p.playersInList[p.playerList[i].playerId] = 0;
str.writeBits(1, 1);
str.writeBits(2, 3);
} else {
Engine.playerMovement.updatePlayerMovement(p.playerList[i], str);
p.playerList[p.playerListSize++] = p.playerList[i];
}
}
NOTE: This is even more effictive if your updating is based on region objects...