How to fix matchmaking when only a few users are existing?

Hi Photon Community!

In my project, matchmaking works in a way now is that it search for available rooms and checks if there's any user in them. And if not, then it starts a room itself and wait for users to join.

It works perfectly when one of the users waits until it has created its room, and when it starts to joining, it finds the room and joins. No waiting would be needed if there would be more rooms to join, so there would be 5-10 users.

But the problem is for example when there're only two players, and the two players start the matchmaking at the same time, there's a chance that they can't find each other. They both try to find a different room, and they both create a room on their own.

What is the best practice of solving this? Creating room and waiting first, and joining to a different room after a few seconds?

Comments

  • Maybe the problem could be solved only if a user could be on Game server (to be in a room waiting for others to join) and on the Master server (to do matchmaking and check all the different rooms)? Is it possible to be on those two servers at the same time?
    Or am I missing something?
  • KaiserludiKaiserludi admin
    edited June 23
    Hi @gregtom6.

    Just use opJoinOrCreateRoom() or opJoinRandomOrCreateRoom(). That's exactly what those operations are there for.
    When your two users both do that at the same time, the user whose request arrives at the server first, will create a new room and the other user will join that room.
  • @Kaiserludi and how to use this exactly? Because as I can see, PhotonNetwork doesn't have any static methods like this, and loadBalancingClient.OpJoinRandomOrCreateRoom(...) seems to be an inner method, which is not meant to be used outside I think (at least I could avoid to use any methods of that until now, and I used everything from PhotonNetwork)
  • TobiasTobias admin
    The problem you want to solve is really rare. If a game has next to no players, it's unlikely 2 will decide to play at the same time, so close to one another that they don't match.
    This is usually just a development-time issue, where you start multiple clients to test.
    That said: I agree it's annoying.

    Actually, we did not implement OpJoinRandomOrCreateRoom in PUN 2.
    This is something we can add.

    I think this should work, if added to the PhotonNetwork class:
    public static bool JoinRandomOrCreateRoom(Hashtable expectedCustomRoomProperties, byte expectedMaxPlayers, MatchmakingMode matchingType, TypedLobby typedLobby, string sqlLobbyFilter, string roomName, RoomOptions roomOptions = null, string[] expectedUsers = null)
    {
        if (OfflineMode)
        {
            if (offlineModeRoom != null)
            {
                Debug.LogError("JoinRandomOrCreateRoom failed. In offline mode you still have to leave a room to enter another.");
                return false;
            }
            EnterOfflineRoom("offline room", null, true);
            return true;
        }
        if (NetworkingClient.Server != ServerConnection.MasterServer || !IsConnectedAndReady)
        {
            Debug.LogError("JoinRandomOrCreateRoom failed. Client is on "+ NetworkingClient.Server+ " (must be Master Server for matchmaking)" + (IsConnectedAndReady ? " and ready" : " but not ready for operations (State: "+ NetworkingClient.State + ")") + ". Wait for callback: OnJoinedLobby or OnConnectedToMaster.");
            return false;
        }
    
        typedLobby = typedLobby ?? ((NetworkingClient.InLobby) ? NetworkingClient.CurrentLobby : null); // use given lobby, or active lobby (if any active) or none
    
        OpJoinRandomRoomParams opParams = new OpJoinRandomRoomParams();
        opParams.ExpectedCustomRoomProperties = expectedCustomRoomProperties;
        opParams.ExpectedMaxPlayers = expectedMaxPlayers;
        opParams.MatchingType = matchingType;
        opParams.TypedLobby = typedLobby;
        opParams.SqlLobbyFilter = sqlLobbyFilter;
        opParams.ExpectedUsers = expectedUsers;
    
        EnterRoomParams enterRoomParams = new EnterRoomParams();
        enterRoomParams.RoomName = roomName;
        enterRoomParams.RoomOptions = roomOptions;
        enterRoomParams.Lobby = typedLobby;
        enterRoomParams.ExpectedUsers = expectedUsers;
    
        return NetworkingClient.OpJoinRandomOrCreateRoom(opParams, enterRoomParams);
    }
    


    We can add this in PUN 2.33 or up, I guess.
  • @Tobias We have made a discussion in the Discord channel about that this is not working for both of us after testing, only room creation is happening for both users, but they doesn't join to each other.
    As you asked, I'm sending an email to [email protected] as a reminder.
  • TobiasTobias admin
    We'll look into this early next week but I can't say when this gets fixed. Depends on what the issue is.
    Thx for the mail. I'll use that to ping you.
  • Hey, late comment but wanted to mention that, although PhotonNetwork.JoinRandomOrCreateRoom does not exist, we show you how you can use JoinRandomOrCreateRoom from PUN here.
  • TobiasTobias admin
    I tested some more and now see it should work. Important: The max players value for the random matchmaking should be 0 or match the actual max players value used in the created room(s). Then matchmaking will find or create the room (as far as I can see).

    @gregtom6, let us know if this is not the case.
  • gregtom6gregtom6
    edited July 20
    @Tobias I didn't try to solve this since June, I had other tasks.

    I downloaded the newest Photon Pun 2 version, but it still doesn't work. I have tried the parameters suggested by tagergo in Discord back at June 11 (changing roomName to null instead of "", changing matchingType to MatchmakingMode.FillRoom, using sqlLobbyFilter as null instead of "", using TypedLobby.Default for typedLobby)
    I even tried using PhotonNetwork.JoinRandomOrCreateRoom without any parameters, still no success.

    These are the commands I'm using in this order:
    PhotonNetwork.NickName="test";
    PhotonNetwork.GameVersion = Application.version;
    
    PhotonNetwork.NetworkingClient.AppId = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime;
    
    PhotonNetwork.ConnectUsingSettings();
    

    then the OnConnectedToMaster method gets running, inside that I call:
    PhotonNetwork.OnPlayerEnteredRoom();
    

    then the OnJoinedRoom is running, but the PhotonNetwork.CurrentRoom.PlayerCount will never gets greater than 1.

    OnPlayerEnteredRoom method never runs with JoinRandomOrCreateRoom.
  • gregtom6gregtom6
    edited July 20
    @Tobias I realized the problem was occured, because parallel to JoinRandomOrCreateRoom, I was also overriding OnRegionListReceived, and I called PhotonNetwork.ConnectToRegion too. So it works now in my local region.

    Now my problem is that previously I used PhotonNetwork.ConnectToRegion, as I remember correctly (I can checkout to previous commit if needed), the OnJoinRandomFailed was running if no users were found in a certain region, and I could join to the next region with the next lowest ping.

    But JoinRandomOrCreateRoom method doesn't return to OnJoinRandomFailed. So if I want to achieve a global matchmaking now, should I connect to the lowest pinged region, and if client can't connect to any other users in a certain time or no one is joining to him during this time, then I disconnect and connect to the other region? Unfortunately in this case I would miss users in lower pinged regions if my client is in an another region and it's waiting for an another user to join.

    Isn't there a solution, which parallelly checks every region and if there is a user in a region, then it joins to him? Or if there are multiple users in lower and higher pinged regions too, then client connects to the lowest pinged region user?
Sign In or Register to comment.