VRCPlayerApi.GetPlayers(players) not returning an array with a synced order.
Scena
VRCPlayerApi.GetPlayers(players)
Right now when calling upon this function, it returns a array of players in an instance based off of their join order. However the order of the array can often be inconsistent between players in the instance. The array should be returning as a consistent array for everyone in an instance to avoid syncing problems. When systems are in place that rely on a player order that is consistent among every player it can cause problems and desync issues.Here is a world where an array that is returned by
VRCPlayerApi.GetPlayers(players)
is displayed in its default order. We are able to recreate an inconsistent array order by having people mass join. It very quickly shows an out of sync array order differing from person to person. The screenshots attached is of a same current session.(This bug seems like it can also occur randomly as well. It as is hard to test for, but occurs enough to cause problems when it does happen.)
Log In
Scena
Just going to leave a comment on this, if there is no fix for it it would be nice if SOBA has an option to do something of the sort, handled as a its own operation to sort the array or something.
Nestorboy
I believe this behaviour is intentional, since the order is determine by the order the connections are established to the other users. What you actually want to use in order to determine player join order is to check the player IDs, and that's generally what you want to be using when you're syncing player information over the network. Maybe this is something that should be clarified in the documentation, but I think this is very much intentional.
DrBlackRat
Nestorboy Yeah I don't really get why you would need that to be synced, you would usually want to use the player IDs for anything network related.
Currently the docs state the following:
This is how you get all the Players in your world so you can go through them in a For Loop and apply settings, make changes, look for a particular name, etc. To use it, you first need to create a VRCPlayerApi Array.
It doesn't state that it's not the same for every player / why it is different, so that should probably be added.
Mantibro
Nestorboy If it is intentional, then there is absolutely no reason as to why the order of the array should be this arbitrary. It only makes things more complicated by having to manually sort the array for the purpose of making the list consistent for every player, which I have found no way to successfully achieve, and even if it was achieved it would be overcomplicating something which should not require this much effort to accomplish.
DrBlackRat
Mantibro Here is a very simple way to sort playerApis using bubble sort :D
private VRCPlayerApi[] GetSortedVRCPlayerAPIs()
{
var players = new VRCPlayerApi[VRCPlayerApi.GetPlayerCount()];
VRCPlayerApi.GetPlayers(players);
bool hasSwapped;
do {
hasSwapped = false;
for (int i = 0; i < players.Length - 1; i++) {
if (players[i].playerId < players[i + 1].playerId) {
var temp = players[i];
players[i] = players[i + 1];
players[i + 1] = temp;
hasSwapped = true;
}
}
} while (hasSwapped);
return players;
}
Edit: I still would not recommend doing things like this, as you should really just use the playerID.
Nestorboy
Mantibro It would definitely be convenient if the player array was sorted already, but we don't really know the implementation details or reasoning as to why it is the way it is. It is not unlikely that this function was created for internal purposes initially and then exposed in Udon at some later point
DrBlackRat
Nestorboy I personally try to avoid using it in general for performance reasons. I tend to just have a DataList that I add and remove users from using OnPlayerJoined and OnPlayerLeft. (Edit: This will also not be the same for everyone)