Google Play 服务实时多人游戏的共享种子?
Shared seed for Google Play Services Realtime Multiplayer?
我正在研究
Google Play Services Realtime Multiplayer 游戏,我希望所有客户端在游戏开始前都有一个共享种子(用于初始化 "random" 游戏状态时的确定性)。
我正计划使用 Room.getCreationTimestamp however upon testing not all players receive the same value. Likewise Room.getCreatorId 不能保证与自动匹配对等点的值相同。
有一个视频 Google Play Games: Choosing a specific user 建议节点可以选择一个节点(例如,第一个从排序列表中)来选择做出决定。我担心如果游戏在最大数量的玩家加入之前开始,可能会出现错误行为,因此加入活跃游戏的新玩家可能会不同意谁是老板。我已经草拟了一些临时方法来解决这个问题,还研究了一些共识和领导者选举算法,但不用说它并不漂亮。
有人知道 simpler/safer 生成共享种子的方法吗?
编辑:以下是来自两个不同连接设备的与房间关联的值:
Room.getRoomId():
1. ChoKCQj-99-X_xEQAhABGAAg____________ARDhp87Gh-73-Uk
2. ChoKCQj-99-X_xEQAhABGAAg____________ARC7oOT7-oKouRI
Room.getCreationTimestamp():
1. 1431018058986
2. 1431018047097
Room.getCreatorId():
1. p_COGnzsaH7vf5SRAB
2. p_CLug5Pv6gqi5EhAB
还有Room.getDescription()
returnsnull
这两种情况。
关于 RoomId 的建议有一定的前景,但在不知道 ID 是如何生成的情况下,我怀疑使用前缀是否安全。
编辑:我尝试使用"creator"作为权限,每个节点都可以向创建者索要种子。不幸的是,在我的双节点测试用例中,每个节点都认为自己是创建者。
我有同样的问题要解决。跟随那个视频给了我正确的指示。如视频中所述,解决方案是对参与者数组进行排序,我们假设最低的 participantId 有权选择随机种子。这是我解决问题的方法:
private boolean amItheKing() {
int numberOfParticipants = participants.size();
String[] participantIds = new String[numberOfParticipants];
for (int i = 0; i < numberOfParticipants; i++) {
participantIds[i] = participants.get(i).getParticipantId();
}
Arrays.sort(participantIds);
return (participantIds[0].equals(myId));//the first in the list decide and broadcast the seed
}
然后用在合适的地方:
public void onActivityResult(int requestCode, int responseCode, Intent intent) {
switch (requestCode) {
case RC_WAITING_ROOM:
// we got the result from the "waiting room" UI.
if (responseCode == Activity.RESULT_OK) {
// ready to start playing
Gdx.app.debug(TAG, "Ready to start the game (waiting room returned OK).");
if (amItheKing()) {
int seed = generateSeed();
broadcastSeed(seed);
prepareForStart(seed);
}
} else if (responseCode == GamesActivityResultCodes.RESULT_LEFT_ROOM) {
// player indicated that they want to leave the room
leaveRoom();
} else if (responseCode == Activity.RESULT_CANCELED) {
// Dialog was cancelled (user pressed back key, for instance). In our game,
// this means leaving the room too. In more elaborate games, this could mean
// something else (like minimizing the waiting room UI).
leaveRoom();
}
break;
}
}
我正在研究 Google Play Services Realtime Multiplayer 游戏,我希望所有客户端在游戏开始前都有一个共享种子(用于初始化 "random" 游戏状态时的确定性)。
我正计划使用 Room.getCreationTimestamp however upon testing not all players receive the same value. Likewise Room.getCreatorId 不能保证与自动匹配对等点的值相同。
有一个视频 Google Play Games: Choosing a specific user 建议节点可以选择一个节点(例如,第一个从排序列表中)来选择做出决定。我担心如果游戏在最大数量的玩家加入之前开始,可能会出现错误行为,因此加入活跃游戏的新玩家可能会不同意谁是老板。我已经草拟了一些临时方法来解决这个问题,还研究了一些共识和领导者选举算法,但不用说它并不漂亮。
有人知道 simpler/safer 生成共享种子的方法吗?
编辑:以下是来自两个不同连接设备的与房间关联的值:
Room.getRoomId():
1. ChoKCQj-99-X_xEQAhABGAAg____________ARDhp87Gh-73-Uk
2. ChoKCQj-99-X_xEQAhABGAAg____________ARC7oOT7-oKouRI
Room.getCreationTimestamp():
1. 1431018058986
2. 1431018047097
Room.getCreatorId():
1. p_COGnzsaH7vf5SRAB
2. p_CLug5Pv6gqi5EhAB
还有Room.getDescription()
returnsnull
这两种情况。
关于 RoomId 的建议有一定的前景,但在不知道 ID 是如何生成的情况下,我怀疑使用前缀是否安全。
编辑:我尝试使用"creator"作为权限,每个节点都可以向创建者索要种子。不幸的是,在我的双节点测试用例中,每个节点都认为自己是创建者。
我有同样的问题要解决。跟随那个视频给了我正确的指示。如视频中所述,解决方案是对参与者数组进行排序,我们假设最低的 participantId 有权选择随机种子。这是我解决问题的方法:
private boolean amItheKing() {
int numberOfParticipants = participants.size();
String[] participantIds = new String[numberOfParticipants];
for (int i = 0; i < numberOfParticipants; i++) {
participantIds[i] = participants.get(i).getParticipantId();
}
Arrays.sort(participantIds);
return (participantIds[0].equals(myId));//the first in the list decide and broadcast the seed
}
然后用在合适的地方:
public void onActivityResult(int requestCode, int responseCode, Intent intent) {
switch (requestCode) {
case RC_WAITING_ROOM:
// we got the result from the "waiting room" UI.
if (responseCode == Activity.RESULT_OK) {
// ready to start playing
Gdx.app.debug(TAG, "Ready to start the game (waiting room returned OK).");
if (amItheKing()) {
int seed = generateSeed();
broadcastSeed(seed);
prepareForStart(seed);
}
} else if (responseCode == GamesActivityResultCodes.RESULT_LEFT_ROOM) {
// player indicated that they want to leave the room
leaveRoom();
} else if (responseCode == Activity.RESULT_CANCELED) {
// Dialog was cancelled (user pressed back key, for instance). In our game,
// this means leaving the room too. In more elaborate games, this could mean
// something else (like minimizing the waiting room UI).
leaveRoom();
}
break;
}
}