Google Play 服务实时多人游戏的共享种子?

Posted

技术标签:

【中文标题】Google Play 服务实时多人游戏的共享种子?【英文标题】:Shared seed for Google Play Services Realtime Multiplayer? 【发布时间】:2015-07-17 04:22:30 【问题描述】:

我正在做一个 Google Play Services 实时多人游戏,我希望所有客户端在游戏开始前都有一个共享种子(用于初始化“随机”游戏状态时的确定性)。

我计划使用Room.getCreationTimestamp,但在测试时并非所有玩家都收到相同的值。同样,Room.getCreatorId 对于自动匹配对等点也不能保证是相同的值。

有一个视频Google Play Games: Choosing a specific user 建议对等点可以选择一个对等点(例如,从排序列表中选择一个)来选择做出决定。我担心如果游戏在最大数量的玩家加入之前开始游戏可能会出现行为不端,因此加入活跃游戏的新玩家可能会不同意谁是老板。我已经勾勒出一些临时的方法来解决这个问题,还研究了一些共识和领导者选举算法,但不用说它并不漂亮。

有人知道生成共享种子的更简单/更安全的方法吗?

编辑:以下是来自两个不同连接设备的与房间相关的值:

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() 在这两种情况下都返回null

关于 RoomId 的建议有一定的希望,但在不知道 id 是如何生成的情况下,我怀疑使用前缀是否安全。

编辑:我尝试使用“创建者”作为权限,每个节点都可以向创建者请求种子。不幸的是,在我的两个节点测试用例中,每个节点都认为它是创建者。

【问题讨论】:

我完全不熟悉这个话题,但阅读文档让我想知道房间“变体”是否有用; developer.android.com/reference/com/google/android/gms/games/…. 有点——我可以将变体设置为种子,但只有具有相同变体的其他玩家才能加入该游戏。理想情况下,我会在不限制谁可以加入的情况下开始有 N 个可用玩家的游戏。不过感谢您的建议! Room.Id 怎么样 - 我相信所有玩家都一样。你能得到它的hashcode吗? @ClaytonWilkinson 房间 ID 有一个共同的前缀,但并不相同。我想我可以在 N 个字符之后将其切碎并交叉手指。 (: 【参考方案1】:

我有同样的问题要解决。跟随那个视频给了我正确的指示。如视频中所述,解决方案是对参与者数组进行排序,让我们假设最低的参与者 ID 有权选择随机种子。这是我如何解决问题的:

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;
    


【讨论】:

谢谢,我正在寻找类似的东西。我担心的是,如果我让 4 人游戏提前开始(只有 2 人加入后),那么有可能会有第 3(和/或)第 4 玩家加入,这样一个同伴认为游戏是从 2 开始的,而另一个相信游戏是从 3 或 4 开始的,因此对于谁是王者可能会有不同的想法。

以上是关于Google Play 服务实时多人游戏的共享种子?的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 Google Play 游戏服务的实时多人游戏中使用机器人玩家?

当应用程序进入后台时,实时多人 Google Play 游戏服务对等方断开连接

Google Play 游戏服务 - 实时多人游戏 - STATUS_CLIENT_RECONNECT_REQUIRED

如何在实时多人游戏 Google Play 游戏服务中向其他参与者发送有关房间创建的数据

我可以在 Unity Android Free 中使用 Google Play 游戏服务 - 实时多人游戏吗?

Google Play 游戏服务 (GPGS) 实时多人游戏 (RTMP) 在 Android 上永远无法匹配(iOS 工作)