question

arycama avatar image
arycama asked

How to create additional Server Bacfkill Tickets after one has matched?

I am using Unity and trying to achieve the following server+matchmaking setup



  1. Two (or more) players match, server is created. Max game size of say, 32
  2. Server creates a backfill ticket to find more players.
  3. Once the backfill ticket is matched, server makes another backfill ticket.
  4. Server repeats this process until the max player count is reached.

I have steps 1 and 2 working, I am able to match two players, create a backfill ticket, and a 3rd player is able to connect.

However, once the 3rd player connects, I have been unable to add additional players. The server error logs report "CreateServerBackfillTicket: User is a member of too many backfill tickets." in response to trying to create additional backfill tickets from the server, once the first backfill ticket has been matched.

A couple of questions:

Does the ServerBackfillTicket get removed from the queue once it is matched and the player is added,
or is further action needed from the server before it can submit an additional backfill ticket?

Does the server need to poll GetServerBackfillTicketRequest every 6 seconds like a regular client matchmaking ticket? Can a server poll more often? (Is polling even neccessary, can I just wait for the callback to be invoked?)

The relevant code snippets are below:
PlayFabMultiplayerAgentAPI calls OnServerActive,

private void OnServerActive()
{
    var titleEntity = new EntityKey(PlayFabSettings.TitleId, "title");
    var entityRequest = new GetEntityTokenRequest() { Entity = titleEntity };
    PlayFabAuthenticationAPI.GetEntityToken(entityRequest, OnGetEntityToken, UpdateMessageError);
}

This calls OnGetEntityToken,
private void OnGetEntityToken(GetEntityTokenResponse result)
{
    var matchId = PlayFabMultiplayerAgentAPI.SessionConfig.SessionId;
    var getMatchRequest = new GetMatchRequest() { MatchId = matchId, QueueName = queueName, ReturnMemberAttributes = true };
    PlayFabMultiplayerAPI.GetMatch(getMatchRequest, OnGetMatchServer, Debug.LogError);
}


Which calls OnGetMatchServer,
private void OnGetMatchServer(GetMatchResult result)
{
    var backfillRequest = new CreateServerBackfillTicketRequest() { GiveUpAfterSeconds = backfillTimeout, Members = result.Members, QueueName = queueName, ServerDetails = result.ServerDetails };
    PlayFabMultiplayerAPI.CreateServerBackfillTicket(backfillRequest, createResult => StartCoroutine(OnCreateServerBackfillTicket(createResult)), UpdateMessageError);
}


Then starts coroutine OnCreateServerBackfill Ticket
private IEnumerator OnCreateServerBackfillTicket(CreateServerBackfillTicketResult result)
{
    serverWaitingForMatch = true;
    while (serverWaitingForMatch)
    {
        var request = new GetServerBackfillTicketRequest() { QueueName = queueName, TicketId = result.TicketId };
        PlayFabMultiplayerAPI.GetServerBackfillTicket(request, OnGetServerBackfillTicket, UpdateMessageError);


        // Can poll up to 10 times per minute on client, not sure about server though
        yield return new WaitForSeconds(6);
    }
}


Which then polls the ServerBackfillTicketrequest every 6 seconds, and calls OnGetServerBackfillTicket
private void OnGetServerBackfillTicket(GetServerBackfillTicketResult result)
{
    if (result.Status != "Canceled" && result.Status != "Matched")
    {
        return;
    }


    // This will stop the polling coroutine
    serverWaitingForMatch = false;

    // Create a new backfill ticket request
    var matchId = PlayFabMultiplayerAgentAPI.SessionConfig.SessionId;
    var getMatchRequest = new GetMatchRequest() { MatchId = matchId, QueueName = queueName, ReturnMemberAttributes = true };
    PlayFabMultiplayerAPI.GetMatch(getMatchRequest, OnGetMatchServer, Debug.LogError);
}


Which checks to see if the result is cancelled or matched, and if so, begins the process again by calling OnGetMatchServer (Above)



Hopefully this is enough info.

To summarise, I am mostly looking for the intended way to create a backfill ticket, and then once that ticket has been matched, create additioanl tickets if neccessary to achieve the desired player count. (I want players to be able to join one by one, rather than waiting for a large group of players to be able to join the game)

If there was an example showing how to proeprly use Server backfill tickets, I'm sure many others would also find it useful.

Thanks for any help!







sdksMatchmaking
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Seth Du avatar image
Seth Du answered

According to your code, it seems you are using while(true) loop to create backfill ticket. Since PlayFab API is asynchronous in Unity SDK, it definitely exceeds the limit immediately. Server can only create 5 tickets per minute, which is stated in [Game Manager] -> [Title settings] -> [Limits]

The behavior of backfill ticket is that, when the number of total connected players is less than minimum number of the queue, one backfill ticket will match enough players to fill in the slots until it meets min number. After that, each server backfill ticket will only open one slot for one player to join the match. At this moment, you may create ticket one by one and only create the new one when a player joins. Otherwise, you can create 5 tickets per minute until the number matches your matchmaking queue configuration. Anyway, backfill process should be dynamically changed according to the connected players, a single while loop usually cannot fulfill the requirement.

2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

arycama avatar image arycama commented ·

Update: I think I have everything working now. I just needed to wait 6 seconds after the backfill request was matched, before making a new request.

Thanks to this answer:
https://community.playfab.com/comments/45426/view.html

I assume it's because you can only make 5 backfill tickets per minute, or once every 12 seconds. So waiting 6 seconds after polling, and then another 6 seconds before making a new ticket would keep you under that limit.

If anyone else is struggling, just add "yield return new WaitForSeconds(6);" to line 11 of the last block of code I posted.

1 Like 1 ·
arycama avatar image arycama commented ·

Thanks for the response.

The while loop is not creating a new ticket every iteration, it is only polling for the response every 6 seconds.

The callback (OnGetServerBackfillTicket) checks to see if the ticket is matched, and once it is matched, it will set "serverWaitingForMatch" to false, which stops the infinite loop.

After this, it starts the process again, by using "GetMatch", followed by "CreateServerBackfillTicket", which should be fine as the previous backfill ticket would have been matched or cancelled.

Regadless of my code, can you be more specific about which API functions I should use, and the order to use them to fulfill my goals?

(Eg I want to create a backfill ticket for one player, and then once that is matched, create another backfill ticket and so on, until the max player count is reached)

Thanks.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.